如果结构化绑定不能为constexpr,为什么可以在constexpr函数中使用它们? [英] If structured bindings cannot be constexpr why can they be used in constexpr function?

查看:222
本文介绍了如果结构化绑定不能为constexpr,为什么可以在constexpr函数中使用它们?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据此答案,显然没有充分的理由说明为什么不允许结构化绑定为constexpr,但这是标准仍然禁止它.但是,在这种情况下,是否也不应禁止在constexpr函数内部使用结构化绑定?考虑一个简单的代码段:

According to this answer apparently there is no good reason why structured bindings are not allowed to be constexpr, yet the standard still forbids it. In this case, however, shouldn't the use of the structured bindings inside the constexpr function also be prohibited? Consider a simple snippet:

#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);
}

gcc c语不会在编译代码时引起麻烦.代码是格式不正确还是实际上是允许的?

Both gcc and clang does not cause trouble compiling the code. Is the code ill-formed either way or is this one actually allowed?

推荐答案

对于函数声明,constexpr说明符是对编译器的断言,即所声明的函数可以在常量中进行评估表达式,即可以在编译时求值的表达式.但是,声明内的对象初始化不需要在声明说明符内包含constexpr即可成为常量表达式.

In the case of function declaration, the constexpr specifier is an assertion made to the compiler that the function being declared may be evaluated in a constant expression, i.e. an expression that can be evaluated at compile-time. Nevertheless the object initialization inside a declaration does not need to have constexpr inside its declaration specifier to be a constant expression.

缩略语:constexpr函数可能暗示恒定表达式,但是恒定表达式初始化不需要关联的声明具有constexpr说明符.

Shorter: constexpr function may imply constant expression but constant expression initialization does not need that the associated declaration has a constexpr specifier.

您可以在C ++标准[dcl.constexpr]中进行检查:

You can check this in the C++ standard [dcl.constexpr]:

对constexpr函数的调用产生的结果与对同等的非constexpr函数的调用产生的结果相同 除了所有方面

A call to a constexpr function produces the same result as a call to an equivalent non-constexpr function in all respects except that

-对constexpr函数的调用可以出现在常量表达式中[...]

— a call to a constexpr function can appear in a constant expression[...]

这是表达式的评估,用于确定表达式是否为 常数表达式[expr.const]:

This is the evaluation of an expression that determines if an expression is a constant expression [expr.const]:

表达式 e 是一个核心常量表达式,除非 e evaluation [...]会评估以下之一>表情 [...]

An expression e is a core constant expression unless the evaluation of e [...] would evaluate one of the following expression[...]

声明不是 expression ,因此,无论对象中是否存在constexpr说明符,被声明对象的初始化都是常量表达式.宣言.

A declaration is not an expression, so an initialization of an object being declared is a constant expression irrespective of the presence or not of a constexpr specifier in the declaration.

最后,在[dcl.constexpr]中,指定constexpr函数必须使得存在可以将其主体评估为恒定表达式的参数:

Finally, in [dcl.constexpr], it is specified that a constexpr function must be such that there exist parameters for which its body can be evaluated as a constant expression:

对于既不是默认值也不是模板的constexpr函数或constexpr构造函数(如果没有参数) 存在值,因此对函数或构造函数的调用可以是的求值子表达式 核心常量表达式(8.20),或者对于构造函数而言,某些对象的常量初始值设定项(6.6.2), 程序格式错误,无需诊断.

For a constexpr function or constexpr constructor that is neither defaulted nor a template, if no argument values exist such that an invocation of the function or constructor could be an evaluated subexpression of a core constant expression (8.20), or, for a constructor, a constant initializer for some object (6.6.2), the program is ill-formed, no diagnostic required.

当声明constexpr int a时,编译器期望a被常量表达式初始化,而表达式foo({1,2})是常量表达式,因此您的代码格式正确.

When you declare constexpr int a the compiler expects a to be inialized by a constant expression and the expression foo({1,2}) is a constant expression, so your code is well formed.

PS:尽管如此,函数局部变量声明中的声明说明符(静态,thread_local => static)暗示该函数不能声明为constexpr.

PS: Nevertheless, declaration specifiers (static, thread_local=>static) in the the declaration of function local variable implies that the function cannot be declared constexpr.

这篇关于如果结构化绑定不能为constexpr,为什么可以在constexpr函数中使用它们?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆