考虑以下简化的模板元编程代码,该代码实现了Angle
类,该类在内部存储模数减少了360度的值。
#include <iostream>
#include <typeinfo>
template<int N, int D>
struct Modulus
{
static auto const value = N % D;
};
template<int N>
struct Angle
{
static auto const value = Modulus<N, 360>::value; // ERROR
//static int const value = Modulus<N, 360>::value; // OK
//static auto const value = N % 360; // OK
typedef Angle<value> type;
};
int main()
{
std::cout << typeid(Angle<30>::type).name() << "\n";
std::cout << typeid(Angle<390>::type).name() << "\n";
return 0;
}
上的输出
使用Visual C ++ 2010 Express,我可以static auto const = Modulus<N, 360>::value
,但是使用MinGW gcc 4.7.2(Nuwen distro)或Ideone(gcc 4.5.1),我必须明确地将类型表示为{ {1}}或者我必须将static int const value = Modulus<N, 360>::value
与完整的模块表达式auto
一起使用。
问题:根据新的C ++ 11标准,哪个编译器是正确的?
答案 0 :(得分:1)
代码有效。 Visual C ++接受它是正确的,gcc拒绝它是错误的(为了完整性,Clang 3.1也接受代码)。规范声明(C ++ 11 7.1.6.4 [dcl.spec.auto] / 4):
auto
类型说明符也可用于声明静态数据成员,其中出现大括号或等号初始值在类定义的成员规范中。
您的value
是静态数据成员。它有一个大括号或等于初始化程序(即声明的= Modulus<N, 360>::value
部分),初始化程序出现在成员规范中类定义(即,凡人可能称之为“内联初始化器”)。