- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的问题源于钻研std::move
在 return
语句,例如在以下示例中:
struct A
{
A() { std::cout << "Constructed " << this << std::endl; }
A(A&&) noexcept { std::cout << "Moved " << this << std::endl; }
};
A nrvo()
{
A local;
return local;
}
A no_nrvo()
{
A local;
return std::move(local);
}
int main()
{
A a1(nrvo());
A a2(no_nrvo());
}
打印 (MSVC,/std:c++17, release)
Constructed 0000000C0BD4F990
Constructed 0000000C0BD4F991
Moved 0000000C0BD4F992
我对返回按值的函数中的 return 语句的一般初始化规则感兴趣,以及在使用
std::move
返回局部变量时适用哪些规则。如上图所示。
- Evaluates the expression, terminates the current function and returns the result of the expression to the caller after implicit conversion to the function return type. [...]
- when returning from a function that returns by valuelike so
return other;
回到我的例子,根据我目前的知识 - 与上述规则相反 -
A a1(nrvo());
是声明
直接初始化 a1 与纯右值
nrvo()
.那么究竟哪个对象是
复制初始化 如 cppreference.com 中所描述的返回语句?
std::move
案例
std::move(local)
有类型
A&&
但是
no_nrvo()
声明返回类型
A
,所以这里
returns the result of the expression to the caller after implicit conversion to the function return type
A glvalue of any non-function, non-array type T can be implicitly converted to a prvalue of the same type. [...] For a class type, this conversion [...] converts the glvalue to a prvalue whose result object is copy-initialized by the glvalue.
A&&
至
A
A
的移动构造函数 使用,这也是此处禁用 NRVO 的原因。这些规则是否适用于这种情况,我是否正确理解它们?此外,他们再次说
复制初始化 由泛左值但
A a2(no_nrvo());
是直接初始化。所以这也涉及到第一种情况。
最佳答案
在深入了解这些细节时,您必须小心使用 cppreference.com,因为它不是权威来源。
So which object exactly is copy-initialized as described at cppreference.com for return statements?
To convert from A&& to A A's move constructor is used, which is also why NRVO is disabled here. Are those the rules that apply in this case, and did I understand them correctly?
return std::move(local);
,不是
local
返回的是
A&&
这是调用
std::move()
的结果.这没有名称,因此强制性 NRVO 不适用。
I think this should be an Lvalue to rvalue conversion:
A&&
返回者
std::move()
绝对不是左值。它是一个 xvalue,因此已经是一个右值。这里没有发生左值到右值的转换。
but A a2(no_nrvo()); is a direct initialization. So this also touches on the first case.
return
的一部分语句不受该函数调用方式的任何影响。同样,函数的返回参数在调用点的使用方式不受函数定义的影响。
an
由函数的结果直接初始化。实际上,这意味着编译器将为
an
使用相同的内存位置。对象作为函数的返回值。
A a1(nrvo());
,感谢 NRVO,分配给
local
的内存位置与函数的结果值相同,恰好是
a1
已经。有效,
local
和
a1
一直都是同一个对象。
A a2(no_nrvo())
,
local
有自己的存储,以及函数的结果,又名
a2
是从它移动构造的。有效,
local
搬进
a2
.
关于c++ - 按值返回的函数的 return 语句中的初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68883573/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!