c++ - constexpr 和带有模板类的静态成员声明

标签 c++ templates static declaration constexpr

请看代码:

#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++语言规范告诉我原因。

最佳答案

C<N>::p_1 的两种可能的定义并不像它们看起来那样等效,因为 C<N>::n可以在给定 N 的第一次实例化之前的任何时间显式专门化.

template<int N>
struct C
{
  static constexpr int n = N;
  using this_type_1 = C<n>;
  static this_type_1* p_1;
};

template<int N>
C<N>* C<N>::p_1; // ERROR

template<>
constexpr int C<5>::n = 6;

int main()
{
    C<6>* p = C<5>::p_1;
}

如果编译器接受 C<N>::p_1 的定义,它的声明类型可能不正确。

关于c++ - constexpr 和带有模板类的静态成员声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14419679/

相关文章:

java - 内部类中的静态字段

java - Java 中的静态变量

c++ - 迭代 `std::multiset` 的唯一元素

c++ - 在 C++11 中结合 vector 和整数?

c++ - clang 3.3 和 constexpr 约束

c++ - 根据编译时条件在类型之间进行选择的惯用方式

actionscript-3 - AS3 类型错误 : Error #1007: Instantiation attempted on a non-constructor

c++ - 当 Python 嵌入到 C++ 中时,numpy 导入失败

c++ - 订单 : An Analysis on Point Sorting

c++ - 编译时构造函数选择