gpt4 book ai didi

c++ - 参数是对文字类型的引用时的常量函数

转载 作者:行者123 更新时间:2023-12-02 09:53:17 25 4
gpt4 key购买 nike

constexpr int func(int const& rf){
return rf;
}
int main(){
constexpr int value = func(0);
}
考虑上面的代码,它将被编译并且格式正确,但是我对此感到困惑。根据 [[stmt.return#2]]

the return statement initializes the glvalue result or prvalue result object of the (explicit or implicit) function call by copy-initialization from the operand.


所以,我认为 return 语句将等同于以下内容:
constexpr void func(int const& rf){
constexpr int value = rf; //#1
}
int main(){
func(0);
}
但是,这一次,代码格式不正确。因为它受以下规则的约束:

an id-expression that refers to a variable or data member of reference type unless the reference has a preceding initialization and either

  • it is initialized with a constant expression or
  • its lifetime began within the evaluation of e;

rf没有预先初始化,并且它的生命周期在进入函数体之前就开始了,因此,当评估 rf#1 ,它的生命周期不在此表达式的计算范围内开始。所以,表达式不是常量表达式,但是,作为等价形式,我想知道为什么第一个代码在对象 value时格式正确从操作数 rf 复制初始化?
更新
我认为这些问题简单地等同于这种形式:
constexpr int func(){
int result = 0;
return result;
}

int main()
{
constexpr int x = func();
}
当左值到右值转换应用于操作数 result return 声明,它会违反以下规则:

an lvalue-to-rvalue conversion unless it is applied to

  • a non-volatile glvalue of integral or enumeration type that refers to a complete non-volatile const object with a preceding initialization, initialized with a constant expression

result用常量表达式而不是 const 对象初始化,因此它违反了此规则并且不是常量表达式。为什么它实际上是格式良好的?为什么 constexpr 函数可以返回非常量变量?到目前为止,我还没有找到任何额外的规则来允许这样做。

最佳答案

So, I think the return statement would be equivalent to the following


如果等价的意思是如果它有效,它将是复制初始化,那么是的。但它是无效的,所以称它为等价是不正确的。

However, as the equivalent form, I wonder why the first code is well-formed when the object value copy-initialized from the operand rf?


因为复制初始化在这里并不重要。原因是
constexpr int value = func(0);
是有效的,而
constexpr int value = rf;
不是,仅仅是由于初始化中使用的表达式的属性。复制初始化对取消第二个或允许第一个没有任何作用。
对于第一个示例, func(0)是必须满足常量表达式要求的表达式。它是一个产生纯右值的表达式。该纯右值最终是从某个引用中复制初始化的。然而,该引用指的是仅在不断评估期间存在的某些对象。 IE。为保存 0 而创建的“临时”在调用函数之前。这就是为什么prvalue结果可以被常数评估,然后用来初始化 constexpr。多变的。
在第二个示例中, rf另一方面,不能在常量表达式中使用。对于您引用的那一段。 constexpr函数仍然是常规函数,也可以“在运行时”调用。此外,编译器不必不断折叠它们。因此,无论何时评估它们,它们都必须是有效的函数。因此,由于 rf无论函数如何调用,它都不能在常量表达式中使用,它不能用于初始化必须由函数本身内部的常量表达式无条件初始化的东西。
把它放在标准的框架中,初始化的完整表达式可以访问在其中创建的对象。在上下文中
constexpr int value = func(0);
rf绑定(bind)到作为完整表达式的一部分而存在的对象。所以我们可以访问它。然而,在
constexpr int value = rf;
rf不绑定(bind)到在该完整表达式中开始的对象整个生命周期。
每个 constexpr变量声明是它自己的独立“上下文”,用于检查常量表达式的有效性。在这方面,它们彼此脱节。

result is initialized with a constant expression but not a const object, So it violate this rule


它违反了该项目符号,但该子句中有几个项目符号可以替代有效的左值到右值转换。它非常符合

an lvalue-to-rvalue conversion unless it is applied to

  • a non-volatile glvalue of literal type that refers to a non-volatile object whose lifetime began within the evaluation of e;
result是文字类型,在评估 func() 期间出现(以及退出) .因此,它是格式良好的。

关于c++ - 参数是对文字类型的引用时的常量函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62514315/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com