c++11 - 带有部分模板特化的 static_assert

标签 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_assert , S<int>实例化将失败。哪怕是一个人typedef S<int> Si;将无法编译。 (海湾合作委员会 4.9.2 Cygwin)

我的目标不是为了 S<double>foo() 处失败调用,但是在模板本身的实例化时,并且带有有意义的错误消息。我知道我可以做类似 typename T::nonexistent_type t; 的事情在主模板中,这将阻止模板编译,但不如 static_assert信息。 (注意:将 static_assert 放在主模板的函数定义中仍然无法编译 S<int> )

为什么static_assert即使该模板未实例化也会失败?这是标准规定的(或者可能是“未指定的”)吗?有没有办法让 static_assert 失败我希望的方式?

最佳答案

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

你的代码是一种奇怪的迂回方式做类似的事情

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

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

关于c++11 - 带有部分模板特化的 static_assert,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30286296/

相关文章:

c++ - 在 C++ 11 中使用 initializer_list 初始化 unique_ptr

c++ - 如何将 "using"用于函数?

c++ - 按字母顺序排序结构数组

c++ - 为什么我的模板特化检查不足以正确处理相应的类型?

C++ 入门第 5 版函数模板特化

c++ - 专门用于指针的模板

c++ - 如果 lambda 中带有 static_assert 的 constexpr,哪个编译器是正确的?

c++ - CLion 无法解析类型 std::unordered_map,即使它提示我包含 header 并且编译工作正常

c++ - 编译时检查以确保结构中的任何地方都没有填充

c++ - 如何静态检查两个比率是否相等?