static_assert 具有部分模板专业化

static_assert with partial template specialization

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();

我希望 "master template" 永远不会在 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 即使未实例化该模板也会失败?这是标准强制要求的(或者 "unspecified")吗?有没有办法让 static_assert 以我希望的方式失败?

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

你的代码是一种奇怪的迂回方式,可以做类似

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

这清楚地向编译器传达了表达式和模板参数之间的依赖关系,并且更加清晰易读。实际上,我不太清楚您是想让整数类型的编译失败,还是非整数类型的编译失败。