像在Clang的模板实例化(3.8)和GNU C ++(4.9)的规则看起来是不一样的。这是一个例子:
#include <cstddef>
template <bool>
class Assert {
Assert(); // private constructor for Assert<false>
};
template <>
class Assert<true> { // implicit public constructor for Assert<true>
};
template <size_t N>
class A {
};
template <class T, size_t N>
T foo(A<N>) {
return T(N - 1);
}
template <class T>
T foo(A<0>) { // foo is not defined for N=0
Assert<false>();
return T(0);
}
int main(int argc, char **argv) {
foo<int>(A<3>());
return 0;
}
这个最小的示例显示了一个模板函数,foo
该函数在类型T
和自然数上进行了概括N
。未为定义此函数N=0
,因此,Assert
如果使用这种方法,我想使用该类来表示编译器错误。
该代码被GNU编译器(以及Visual C ++ 2015)接受,但是Clang提供了“调用类的私有构造函数Assert<false>
”错误。
那么谁是对的?正如我所看到的,没有的要求foo<T,0>
,因此无需实例化此模板...
编辑:接受的标准锵的解释,什么是执行模板参数编译时检查的规范呢?
我相信clang是正确的,因为Assert<false>
它不是依赖类型。
http://en.cppreference.com/w/cpp/language/dependent_name
在模板定义时查找并绑定非相关名称。这种结合保持即使在模板实例化的角度来看,有一个更好的匹配:
不要做不能有效的专业化。使它们通用,并使用static_assert(具有从属值)检查无效的模板参数类型/值。static_assert(std::is_same<T, int>::value)
要么static_assert(N != 0)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句