Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ MSVC中的模板静态定义和显式专门化实例化错误_C++_Templates_Language Lawyer_Explicit Specialization_Explicit Instantiation - Fatal编程技术网

C++ MSVC中的模板静态定义和显式专门化实例化错误

C++ MSVC中的模板静态定义和显式专门化实例化错误,c++,templates,language-lawyer,explicit-specialization,explicit-instantiation,C++,Templates,Language Lawyer,Explicit Specialization,Explicit Instantiation,我想知道为什么下面的代码在gcc中运行得很好 #include <iostream> using namespace std; template<typename T> struct F { static T const value; }; template<> struct F<int> { // Specialization static int const value; }; template struct F<

我想知道为什么下面的代码在gcc中运行得很好

#include <iostream>
using namespace std;

template<typename T>
struct F { 
  static T const value;
};

template<> 
struct F<int> { // Specialization
    static int const value; 
}; 

template struct F<int>;

template<typename T>
T const F<T>::value = sizeof(T);

template<>
int const F<int>::value = 42;

int main() {

    struct F<int> ma;
    cout << ma.value;

    return 0;
}
#包括
使用名称空间std;
模板
结构F{
静态T常数值;
};
模板
结构F{//专门化
静态int常量值;
}; 
模板结构F;
模板
常数F::value=sizeof(T);
模板
int const F::value=42;
int main(){
结构F-ma;
不能太久;没有阅读
  • msvc 2012正确拒绝标记为
    //错误C2998的行

  • 然而,前一个诊断是错误的,应该被接受;因为它是编译器的一部分

注意:可以找到与C2950相关的错误报告


关于 msvc 2012发布有关线路的诊断是错误的

template<class T> struct A;

template<>
struct A<int> { };

template struct A<int>; // legal

int main () { }

措辞变化:C++03与C++11

14.7.2p5从C++11开始有了一些新的措辞,这是在以下缺陷报告之后出现的:

14.7.2p5
显式实例化
[temp.Explicit]

对于给定的一组模板参数,如果模板的显式实例化出现在该模板的显式专门化声明之后,则显式实例化无效

注意:感谢@引起对先前链接的DR


关于 此错误是准确的;您所指的不是依赖于模板参数的内容,这意味着您不应该对所讨论的定义使用
template

template<class T> struct A;

template<>
struct A<int> { };

template struct A<int>; // legal

int main () { }
较新版本的
gcc
发布了与此相关的诊断,而clang正确地拒绝了此类定义

template<class T> struct A;

template<>
struct A<int> { 
  static int const value;
};

template<> int const A<int>::value = 42; // ill-formed, `value` does not depend on
                                         //              any template parameter since it's
                                         //              explicitly a part of `A<int>`

int main () { }
模板结构A;
模板
结构A{
静态int常量值;
};
模板int const A::value=42;//格式错误,`value`不依赖于
//任何模板参数,因为它是
//明确地是` a'的一部分`
int main(){}
gcc=>foo.cpp:8:22:警告:A::value的模板头太多(应为0)
clang=>foo.cpp:8:1:错误:变量“value”的声明中存在无关的“template”
msvc=>foo.cpp(8):错误C2998:“const int A::value”:不能是模板定义
上述诊断是正确的


该行违反了标准的以下部分:

14.7.3p5
明确专业化
[temp.expl.spec]

显式专用类模板的成员的定义方式与普通类的成员相同,并且不使用
模板
语法。定义显式专用成员类的成员时也是如此


你的解释对我来说似乎完全合理。程序不正常,但不是因为你说的,而是因为
template int const F::value=42;
应该没有
template
(最新的gcc it)。显式实例化遵循显式专门化声明(这也是一个定义)GCC有很多扩展,允许你做C++标准不允许的事情。默认情况下,这些东西仍然允许使用“-ANSI -迂腐”标志编译。@ DIK0146编译器错误在代码内的注释中。在VC 2012/2013中不需要设置允许C++ 11。默认情况下,它是启用的。是的,C950是。
template<class T> struct A;

template<>
struct A<int> { 
  static int const value;
};

template<> int const A<int>::value = 42; // ill-formed, `value` does not depend on
                                         //              any template parameter since it's
                                         //              explicitly a part of `A<int>`

int main () { }