W.F*_*.F. 12 c++ language-lawyer constexpr c++17 structured-bindings
根据这个答案,显然没有充分的理由说明为什么不允许结构化绑定是constexpr,但标准仍然禁止它.但是,在这种情况下,是否应该禁止在constexpr函数中使用结构化绑定?考虑一个简单的片段:
#include <utility>
constexpr int foo(std::pair<int, int> p) {
auto [a, b] = p;
return a;
}
int main() {
constexpr int a = foo({1, 2});
static_assert(a == 1);
}
Run Code Online (Sandbox Code Playgroud)
在函数声明的情况下,说明constexpr符是对编译器的断言,声明的函数可以在常量表达式中计算,即可以在编译时计算的表达式.然而,声明中的对象初始化不需要constexpr在其声明说明符中包含常量表达式.
更短:constexpr函数可能意味着常量表达式,但常量表达式初始化不需要关联的声明具有constexpr说明符.
您可以在C++标准[dcl.constexpr]中进行检查:
对constexpr函数的调用产生与在所有方面调用等效的非constexpr函数相同的结果,除了
- 对constexpr函数的调用可以出现在常量表达式中[...]
这是对表达式的求值,该表达式确定表达式是否为常量表达式[expr.const]:
表达式Ë是核心常量表达式除非评价的ë [...]将评估以下中的一个表达 [...]
声明不是表达式,因此声明的对象的初始化是一个常量表达式,而不管声明中是否存在constexpr说明符.
最后,在[dcl.constexpr]中,指定一个constexpr函数必须使得存在可以将其主体作为常量表达式求值的参数:
对于既不是默认也不是模板的constexpr函数或constexpr构造函数,如果不存在参数值,则函数或构造函数的调用可以是核心常量表达式的评估子表达式(8.20),或者对于构造函数,某些对象的常量初始化程序(6.6.2),程序格式错误,无需诊断.
当您声明constexpr int a编译器期望a通过常量表达式进行初始化并且表达式foo({1,2})是常量表达式时,您的代码就会很好地形成.
PS:尽管如此,函数局部变量声明中的声明说明符(static,thread_local => static)意味着无法声明该函数constexpr.
| 归档时间: |
|
| 查看次数: |
815 次 |
| 最近记录: |