Col*_*mbo 12 c++ assert language-lawyer constant-expression c++14
在assert从-macro <cassert>提供了保证条件满足一个简洁的方式.如果参数的计算结果为true,则不会产生任何进一步的影响.但是,在这种情况下,它的调用是否也可以在常量表达式中使用?
这是由LWG 2234处理的,constexpr在引入了对功能的轻松限制后,它又引起了关注.
拟议决议:
这个措辞与N3936有关.
在17.3 [定义]中将以下新定义引入现有列表:
常量子表达式 [defns.const.subexpr]
一个表达式,其作为条件表达式CE(5.16 [expr.cond])的子表达式的评估 不会阻止CE成为核心常量表达式(5.20 [expr.const]).
按照指示在19.3 [断言] p1之后插入一个新段落:
- ? - 表达式
assert(E)是一个常量子表达式([defns.const.subexpr]),如果有的话
NDEBUG定义在断言(E)出现的点,或E上下文转换为
bool(4 [conv]),是一个常量子表达式,其值为true.
这个解决方案引入了一个常量子表达式的概念- 本质上是一个表达式,它本身不是(必然)一个常量表达式,但可以在一个表达式中使用.例如,考虑一下
constexpr void f() {
int i = 0;
++i;
}
Run Code Online (Sandbox Code Playgroud)
++i不是常量表达式,因为它修改了生命周期在该表达式之外的对象(§5.20/(2.15)).但是,表达式f()完全是一个常量表达式,因为前一点不适用 - i生命周期开始于f.因此++i是一个常数子表达式,因为++i它不会阻止f()成为常量表达式.
assert?解决方案的第二部分保证assert(E)是一个常量子表达式,如果NDEBUG定义了任何一个,或者参数本身是一个常量子表达式并且求值为true.这意味着调用assert也可以是沼泽标准常量表达式.
以下是格式良好的:
constexpr int check(bool b) {
assert(b);
return 7;
}
constexpr int k = check(true);
Run Code Online (Sandbox Code Playgroud)
b是一个常量子表达式并true在调用中求值check(true),因此assert(b)是一个常量子表达式,因此不会阻止check(true)它成为一个子表达式.
当然,与static_assert模板相同的陷阱也是可能的.鉴于NDEBUG未定义,此定义格式不正确,§7.1.5/ 5无需诊断:
constexpr void fail() {
assert(false);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
256 次 |
| 最近记录: |