是否允许编译器在静态断言中评估重言式
Are compilers allowed to evaluate tautologies in static assert
在模板中提供static_assert
通常很有帮助。在模板根本不应该以某种方式实例化的情况下,我经常这样做
template<typename T, typename = void>
struct S
{
static_assert(false, "Unconditional error");
static_assert(sizeof(T) != sizeof(T), "Error on instantiation");
};
template<typename T>
struct S<T, std::enable_if_t<std::is_integral_v<T>>>
{
// ...
};
即使没有实例化S
,第一个static_assert
也会立即失败,而如果没有实例化将导致主模板,则第二个将成功。
第二static_assert
显然是重言式,但它"取决于"T
才能达到预期的效果。但这能保证吗?编译器是否可以评估这些重言式?
相关规则是 [temp.res]/8:
知道哪些名称是类型名称可以检查每个模板的语法。程序格式不正确,无需诊断,如果:
无法为模板或 constexpr 的子语句生成有效的专用化,如果模板中的语句未实例化,则模板未实例化,或者
[...]
示例中的两个static_assert
都会导致程序格式不正确,但不需要诊断。编译器当然可以计算任意复杂的表达式,以尝试证明无法生成有效的专用化,但并不要求他们这样做。false
当然是一个容易立即验证的情况,所以它被诊断出来也就不足为奇了。
希望始终发出诊断的常见方法是:
// never specialize me!
template <typename T>
struct always_false : std::false_type { };
template <typename T>
constexpr bool always_false_v = always_false<T>::value;
template<typename T, typename = void>
struct S {
static_assert(always_false_v<T>, "Unconditional error");
};
always_false
可以假设地专门化于特定的T
以产生true_type
,所以假设可能存在一个有效的专业化S<T>
。但不要让任何人真正这样做。
相关文章:
- std::condition_variable::wait()如何评估给定的谓词
- c++11评估顺序(未定义的行为)
- 尝试使用 std::vector<std::thread时出现静态断言失败错误>
- uint_not_usable_without_attribute在业力规则中使用数字生成器时静态断言失败
- C++ 使用增强正则表达式库时断言崩溃
- 如何使用"equal to"以外的评估编写开关语句
- 从 exe 文件 (Visual Studio ) 启动时调试断言失败
- 嵌套 if 中没有返回评估
- 如何将向量断言到特征矩阵
- 懒惰的参数评估try_emplace?
- OpenCV - Python 断言错误:SAD 算法 - 立体相机视差图计算
- 在实践中,在运行时为零的乘法中是否有任何"lazy"评估
- 使用 Google Test 对自定义断言函数进行单元测试
- 断言"id < 0"在Qt ActiveX中失败
- 初始值设定项列表构造和静态断言
- 如何改进一堆在已知值范围内评估变量的 else-if 条件?
- C++17:使用 std::optional 来评估枚举是否包含值
- CNTK:->转发或 ->评估某些电脑上的崩溃,而不是其他电脑上的崩溃
- 是否允许编译器在静态断言中评估重言式
- 如何禁用PC lint中静态断言的评估