来自assert
的{{1}} - 宏提供了一种确保满足条件的简明方法。如果参数的计算结果为<cassert>
,则不会产生任何进一步的影响。但是,在这种情况下,它的调用是否也可以在常量表达式中使用?
答案 0 :(得分:9)
这是由LWG 2234处理的,在引入s
函数的轻松约束后,它被引起了注意。
建议的解决方案:
这个措辞与N3936有关。
将以下新定义引入17.3中的现有列表 [定义]:
常量子表达式 [defns.const.subexpr]
一个表达式,其评估为条件表达式CE (5.16 [expr.cond])的子表达式,不会阻止 CE 成为核心常量表达式(5.20 [ expr.const])。
- 醇>
按照指示在19.3 [断言] p1之后插入一个新段落:
- ? - 表达式
constexpr
Eassert(
是一个常量子表达式([defns.const.subexpr]),如果有的话
)
定义在断言(E)出现的位置,或E 从上下文转换为
NDEBUG
(4 [conv]),是一个常量子表达式,其值为bool
。
这个分辨率引入了常量子表达式的概念 - 本质上是一个表达式,它本身不是(必然)一个常量表达式,但可以在一个表达式中使用。考虑例如
true
constexpr void f() {
int i = 0;
++i;
}
不是常量表达式,因为它修改了生命周期在该表达式之外的对象(§5.20/(2.15))。但是,表达式++i
完全是一个常量表达式,因为前一点不适用 - 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);
是一个常量子表达式,并在调用b
中评估为true
,因此check(true)
是一个常量子表达式,因此不会阻止assert(b)
成为一体。
当然,模板中的check(true)
也存在同样的缺陷。鉴于static_assert
未定义,此定义格式不正确,§7.1.5/ 5无需诊断:
NDEBUG