mut*_*oid 0 c++ language-lawyer constexpr c++-concepts c++20
编译器是否保证评估环境constexpr中"tautologies"(例如始终true或false分别)的布尔表达式constexpr?
例如,在以下代码片段(在标有 的行(1))中,我在constexpr环境中调用了一个函数,我打算在non-constexpr传递函数时导致编译时错误。至少我使用的编译器 ( g++-10.0) 是这样做的,即使它也可以意识到表达式总是true不计算它。我问这个问题的原因是 - 据我所知 - 在非 constepxr 上下文中,像这样的表达式i >= std::numeric_limits<int>::min()被优化true为int i.
#include <limits>
constexpr int example_function() { return 1;}
constexpr bool compileTimeErrorDesired = example_function() || true; // (1)
Run Code Online (Sandbox Code Playgroud)
如果(1) 保证in 的行为,则可以在 aconcept中使用它,以执行不同的代码,具体取决于是否可以在编译时评估作为模板参数提供的函数。我实现了一个非常短的 ( 7 lines-of-code) 示例,它在编译器资源管理器中完全做到了这一点。
如果使用非 constexpr 函数调用,行 (1) 是否保证会导致编译时错误?
编辑插入澄清,由于反馈而简化示例。
f() || true如果f不是 constexpr 函数,则保证它不是核心常量表达式:(常量表达式比核心常量表达式更具限制性)[expr.const]/2.2
一个表达式
e是一个核心常量表达式除非的评价e,如下所述抽象机的规则,将评估下列表达式之一:
[...]
比constexpr构造为一个文字类,一个constexpr函数,或一个简单的析构函数的隐式调用其它的函数的调用([class.dtor])[ 注:?重载分析被照常应用- 注完 ];
[...]
如果在需要常量表达式的上下文中使用非常量表达式,还可以保证程序格式错误(需要诊断)。注意||定义为从左到右求值:[expr.log.or]/1
在
||左到右操作员组。操作数都根据上下文转换为bool.true如果其任一操作数为true,false则返回,否则返回。与 不同|,||保证从左到右求值;此外,如果第一个操作数的计算结果为真,则不会计算第二个操作数。
换句话说,true || f()是一个核心常量表达式,因为f()没有被评估,而f() || true不是因为f()被评估。
表达式是否为常量表达式与优化无关——常量表达式是根据抽象机器的规则定义的。