c – MSVC中的模板静态定义和明确的专门化实例化错误

前端之家收集整理的这篇文章主要介绍了c – MSVC中的模板静态定义和明确的专门化实例化错误前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想知道为什么以下代码gcc中运行正常
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. template<typename T>
  5. struct F {
  6. static T const value;
  7. };
  8.  
  9. template<>
  10. struct F<int> { // Specialization
  11. static int const value;
  12. };
  13.  
  14. template struct F<int>;
  15.  
  16. template<typename T>
  17. T const F<T>::value = sizeof(T);
  18.  
  19. template<>
  20. int const F<int>::value = 42;
  21.  
  22. int main() {
  23.  
  24. struct F<int> ma;
  25. cout << ma.value;
  26.  
  27. return 0;
  28. }

http://ideone.com/wvrurz

而在MSVC 2012上,我无法得到它来编译:

  1. #include <iostream>
  2. using namespace std;
  3.  
  4. template<typename T>
  5. struct F {
  6. static T const value;
  7. };
  8.  
  9. template<>
  10. struct F<int> { // Specialization
  11. static int const value;
  12. };
  13.  
  14. //template struct F<int>; // error C2950: 'F<int>' : cannot explicitly instantiate an explicit specialization
  15.  
  16. template<typename T>
  17. T const F<T>::value = sizeof(T);
  18.  
  19. //template<>
  20. //int const F<int>::value = 42; // error C2998: 'const int F<int>::value' : cannot be a template definition
  21.  
  22. int main() {
  23.  
  24. struct F<int> ma;
  25. cout << ma.value;
  26.  
  27. return 0;
  28. }

从我在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的错误报告可以在here找到.

关于C2950

msvc 2012是错误的发出相关行的诊断.

  1. template<class T> struct A;
  2.  
  3. template<>
  4. struct A<int> { };
  5.  
  6. template struct A<int>; // legal
  7.  
  8. 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开始有一些新的措辞,在以下缺陷报告之后就已经到位了:

> @L_403_5@

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声正确地拒绝这样的定义.

  1. template<class T> struct A;
  2.  
  3. template<>
  4. struct A<int> {
  5. static int const value;
  6. };
  7.  
  8. template<> int const A<int>::value = 42; // ill-formed,`value` does not depend on
  9. // any template parameter since it's
  10. // explicitly a part of `A<int>`
  11.  
  12. int main () { }
  1. gcc => foo.cpp:8:22: warning: too many template headers for A<int>::value (should be 0)
  2. clang => foo.cpp:8:1: error: extraneous 'template<>' in declaration of variable 'value'
  3. 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.

猜你在找的C&C++相关文章