c++ - static_assert 依赖于非类型模板参数(gcc 和 clang 的不同行为)

标签 c++ templates language-lawyer c++14 dependent-name

template <int answer> struct Hitchhiker {
  static_assert(sizeof(answer) != sizeof(answer), "Invalid answer");
};

template <> struct Hitchhiker<42> {};

在尝试使用 static_assert 禁用常规模板实例化时,我发现 clang 中的上述代码即使在模板未实例化时也会生成断言错误,而 gcc 仅在使用 42 以外的参数实例化 Hitchhiker 时才会生成断言错误。

摆弄我发现这个断言:

template <int answer> struct Hitchhiker {
  static_assert(sizeof(int[answer]) != sizeof(int[answer]), "Invalid answer");
};

template <> struct Hitchhiker<42> {};

在两个编译器上的行为相同:断言仅在通用模板被实例化时才生效。

标准是怎么说的,哪个编译器是对的?

g++ 4.9.2
clang++ 3.50

最佳答案

两个编译器都是正确的。来自 [temp.res]/8:

If no valid specialization can be generated for a template, and that template is not instantiated, the template is ill-formed, no diagnostic required.

不存在可以从主模板 Hitchhiker 生成的有效特化,因此它是格式错误的,不需要诊断。无论如何,clang 选择发出诊断。

如果你只想允许42,那么干脆不要定义通用模板:

template <int > struct Hitchhiker;
template <> struct Hitchhiker<42> {};

关于c++ - static_assert 依赖于非类型模板参数(gcc 和 clang 的不同行为),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30078818/

相关文章:

C++:获取类实例的大小

c++ - 提高C++编译速度的最佳方法

c++ - C++11 中的数据竞争、UB 和计数器

c++ - 通用类型别名,它们彼此不兼容

c++ - 如何将值从 vector 转换为 C++ 中的映射?

C++模板运算符编译错误

c++ - 基于 lambda arity 的特化函数模板

c - 严格别名是单向的吗?

c++ - C++ 数学特殊函数中的 std::complex<>:技术规范或提案

c++ - C++的语法歧义