Mar*_* A. 10 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<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;
}
Run Code Online (Sandbox Code Playgroud)
在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;
}
Run Code Online (Sandbox Code Playgroud)
从我在n3242§14.7中读到的5
除非显式实例化遵循显式特化的声明,否则显式实例化和显式特化的声明都不应出现在程序中.
我相信情况就是如此.我错过了什么吗?
msvc 2012正确拒绝标记的行// error C2998,
然而,以前的诊断是错误的并且应该被接受; 因为它是在较新版本的编译器中.
注意:可以在此处找到与C2950相关的错误报告.
msvc 2012对有问题的行发出诊断是错误的.
template<class T> struct A;
template<>
struct A<int> { };
template struct A<int>; // legal
int main () { }
Run Code Online (Sandbox Code Playgroud)
该标准规定显式实例化应该包含一个simple-template-id,这正是A<int>它所说的那样; 这是合法的 C++.
14.6.2p3显式实例化[temp.explicit]如果显式实例化是针对类或成员类的,则声明中的elaborated-type-specifier应包含simple-template-id.
14.2p1模板特化的名称[temp.names]模板特化(14.7)可以通过template-id引用:
Run Code Online (Sandbox Code Playgroud)simple-template-id: template-name < template-argument-list_opt >
改变措辞: C++ 03 vs C++ 11
14.7.2p5从C++ 11开始有一些新的措辞,它是在以下缺陷报告之后实现的:
14.7.2p5显式实例化[temp.explicit]对于给定的模板参数集,如果在声明该模板的显式特化之后出现模板的显式实例化,则显式实例化无效.
这个错误是准确的; 你没有提到依赖于模板参数的东西,这意味着你不应该使用有template<>问题的定义.
较新版本的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 () { }
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
以上诊断是正确的.
有问题的行违反了标准的以下部分:
14.7.3p5明确的专业化[temp.expl.spec]显式专用类模板的成员以与普通类成员相同的方式定义,而不是使用
template<>语法.定义显式专用成员类的成员时也是如此.
| 归档时间: |
|
| 查看次数: |
2629 次 |
| 最近记录: |