【发布时间】:2013-01-19 22:42:46
【问题描述】:
请看代码:
#include <iostream>
#include <typeinfo>
template<int N>
struct C
{
static constexpr int n = N;
using this_type_1 = C<n>;
using this_type_2 = C<N>;
static this_type_1* p_1;
static this_type_2* p_2;
};
template<int N>
//C<N>* C<N>::p_1; // <--- error pattern
typename C<N>::this_type_1* C<N>::p_1; // <--- ok pattern
template<int N>
C<N>* C<N>::p_2; // ok
int main(){
std::cerr
<< typeid(C<0>).name() << "\n"
<< typeid(C<0>::this_type_1).name() << "\n"
<< typeid(C<0>::this_type_2).name() << "\n"
;
}
可以用g++-4.7.1和clang++-3.1编译。但它无法使用注释掉的错误模式进行编译。
g++ 错误信息是:
test.cpp:15:13: error: conflicting declaration ‘C<N>* C<N>::p_1’
test.cpp:10:23: error: ‘C<N>::p_1’ has a previous declaration as ‘C<N>::this_type_1* C<N>::p_1’
test.cpp:15:13: error: declaration of ‘C<N>::this_type_1* C<N>::p_1’ outside of class is not definition [-fpermissive]
clang++ 错误信息是:
test.cpp:15:13: error: redefinition of 'p_1' with a different type
C<N>* C<N>::p_1; // error
^
test.cpp:10:23: note: previous definition is here
static this_type_1* p_1;
^
1 error generated.
幸运的是,我发现了一个工作模式。但我不知道为什么无法编译错误模式。请根据C++语言规范告诉我原因。
【问题讨论】:
-
对我来说似乎很像一个错误,因为这一行编译没有问题:
static_assert(std::is_same<C<5>*, typename C<5>::this_type_1*>::value, "Error!");。让我怀疑的是 Clang 3.2 和 GCC 4.7.2 都在抱怨。 VS2012有人吗? -
编译器可能不应该接受第三种变体
template <int N> typename identity<C<N>*>::type C<N>::p_1;。但是这条线到底在哪里?
标签: c++ templates static declaration constexpr