Hol*_*Cat 3 c++ gcc templates static-assert
我注意到奇怪的行为static_assert:
#include <iostream>
template <typename T, unsigned int D> struct Vec
{
static_assert(D && 0, "Invalid dimension for vector!");
};
template <typename T> struct Vec<T, 1> {union {T x, r;};};
template <typename T> struct Vec<T, 2> : Vec<T, 1> {union {T y, g;};};
template <typename T> struct Vec<T, 3> : Vec<T, 2> {union {T z, b;};};
template <typename T> struct Vec<T, 4> : Vec<T, 3> {union {T w, a;};};
int main()
{
Vec<float, 3> v;
v.x = 1;
v.y = 2;
v.z = 3;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它编译得很好:http://ideone.com/wHbJYP.我期待
static_assert(0, "Invalid dimension for vector!");
Run Code Online (Sandbox Code Playgroud)
给我相同的结果,但它导致静态断言失败:http://ideone.com/UEu9Kv.两种情况下gcc都正确吗?如果是这样,为什么?或者它是一个gcc bug?那么,在哪种情况下gcc是正确的?
§14.6[temp.res]/p8:
如果无法为模板生成有效的专业化,并且未实例化该模板,则模板格式错误,无需诊断.
在这两种情况下,都不能为主模板生成有效的专业化static_assert(因为D && 0无论其价值如何都是如此D).由于不需要诊断,编译器可以自由诊断一个(当您使用时0)而不是另一个(当您使用时D && 0).
解决方法:
template <unsigned int D> struct always_false : std::false_type {};
template <typename T, unsigned int D> struct Vec
{
static_assert(always_false<D>::value, "Invalid dimension for vector!");
};
Run Code Online (Sandbox Code Playgroud)
编译器在定义时不能再拒绝它,因为可能存在always_false其value成员的显式特化true.