static_assert具有部分模板特化

时间:2015-05-17 11:17:30

标签: c++11 template-specialization static-assert

template<typename T, typename U = void>
struct S { /* static_assert(0, "type unsupported"); */ };
template<typename T>
struct S<T, typename std::enable_if<std::is_integral<T>::value, void>::type> {
    void foo() {}
};
...
S<int> i;
i.foo();
S<double> d;
// d.foo();

我希望永远不会为int的情况实例化“主模板”,但如果我取消注释static_assertS<int>实例化将失败。即使是单独的typedef S<int> Si;也无法编译。 (GCC 4.9.2 Cygwin)

我想要实现的目标不是S<double>foo()调用时失败,而是在模板本身的实例化时,以及带有意义的错误消息。我知道我可以在主模板中执行类似typename T::nonexistent_type t;的操作,这将阻止模板进行编译,但这不如static_assert消息。 (注意:将static_assert置于主模板中的函数定义中仍然无法编译S<int>

为什么即使该模板未实例化,static_assert也会失败?这个标准是强制性的(或者可能是“未指明的”)吗?有没有办法以我想要的方式static_assert失败?

1 个答案:

答案 0 :(得分:7)

static_assert中的表达式必须依赖于模板参数,如果您希望它只是实例化时间。这是由标准保证的 - 实现可以(但没有义务)检查不依赖于任何模板参数的模板中的static_assertion

你的代码是一种奇怪的迂回方式,比如

template<typename T> struct S {
    static_assert(std::is_integral<T>::value, "type unsupported");
    void foo() {}
};

这清楚地向编译器传达了表达式和模板参数之间的依赖关系,并且更清晰,更易于阅读。我实际上无法弄清楚你是否希望编译为整数类型或非整数类型而失败。