#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; }
而在MSVC 2012上,我无法得到它来编译:
#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>; // error C2950: 'F<int>' : cannot explicitly instantiate an explicit specialization template<typename T> T const F<T>::value = sizeof(T); //template<> //int const F<int>::value = 42; // error C2998: 'const int F<int>::value' : cannot be a template definition int main() { struct F<int> ma; cout << ma.value; return 0; }
从我在n3242§14.7中读到的5
both an explicit instantiation and a declaration of an explicit
specialization shall not appear in a program unless the explicit
instantiation follows a declaration of the explicit specialization.
我相信是这样的.我错过了什么吗?
解决方法
> msvc 2012正确拒绝标记为//错误C2998的行,
>以前的诊断是错误的,应该被接受;因为它是在newer versions的编译器.
关于C2950
msvc 2012是错误的发出相关行的诊断.
template<class T> struct A; template<> struct A<int> { }; template struct A<int>; // legal int main () { }
该标准规定明确的实例化应该包含一个简单的模板id,这正是A< int>是这样说的这是合法的C.
14.6.2p3
Explicit instantiation[temp.explicit]
If the explicit instantiation is for a class or member class,the elaborated-type-specifier in the declaration shall include a simple-template-id.
14.2p1
Names of template specializations[temp.names]
A template specialization (14.7) can be referred to by a template-id:
06001
措辞变更:C 03与C 11
14.7.2p5从C11开始有一些新的措辞,在以下缺陷报告之后就已经到位了:
> 259. Restrictions on explicit specialization and instantiation
14.7.2p5
Explicit instantiation[temp.explicit]
For a given set of template arguments,if an explicit instantiation of a template appears after a declaration of an explicit specialization for that template,the explicit instantiation has no effect.
Note: Kudos to @07004 for bringing attention to the prevIoUsly linked DR.
关于C2998
这个错误是准确的你不是指依赖于模板参数的东西,这意味着你不应该使用模板<>关于有关定义.
较新版本的gcc会对其进行诊断,并且cl声正确地拒绝这样的定义.
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 () { }gcc => foo.cpp:8:22: warning: too many template headers for A<int>::value (should be 0) clang => foo.cpp:8:1: error: extraneous 'template<>' in declaration of variable 'value' msvc => foo.cpp(8) : error C2998: 'const int A<int>::value' : cannot be a template definition以上诊断是正确的.
有关的问题是违反本标准的以下部分:
14.7.3p5
Explicit specialization[temp.expl.spec]
Members of an explicitly specialized class template are defined in the same manner as members of normal class,and not using the
template<>
Syntax. The same is true when defining a member of an explicitly specialized member class.