提问人:EL IAS 提问时间:9/13/2023 最后编辑:Jan SchultkeEL IAS 更新时间:9/13/2023 访问量:57
当“by-value”参数也是“by-value”返回参数时,为什么不能进行复制省略?[复制]
Why cant copy elision take place when a 'by-value' parameter is also the 'by-value' return argument? [duplicate]
问:
在下面的代码片段中,我的函数尝试将其“by-value”参数作为“by-value”返回值返回。我看了一段视频,上面写着:“这里在物理上不可能进行复制省略......”但我不明白为什么我们不能对函数参数和返回值使用相同的内存地址。
std::string foo(std::string s){
return s;
}
我试图通过观看视频来理解它,但看不出这在哪里无法进行复制省略。
答:
0赞
Jan Schultke
9/13/2023
#1
无论谁负责销毁函数参数,它们都不能是在调用站点创建的结果对象。 这是 C++17 所必需的,并且很难/不可能使用 NRVO(1) 来实现函数参数。 考虑此函数并调用:
std::string foo(std::string s);
std::string r = foo("...");
发生的情况是:
- 参数构造自
std::string s
"..."
- 控制权被转移到函数中,函数执行其工作
- 按照实现定义的顺序(2):
- 控制权转移回呼叫者
- 函数参数被任何拥有控制权的人销毁
如果调用方负责销毁,调用方应该如何知道与 是同一个对象?如果不查看 的定义,就不可能知道,否则它需要获取额外的运行时信息,以通知它与结果对象是哪个参数(如果有)是同一个对象。s
r
s
foo
如果被调用方负责销毁,则意味着不可能,因为被销毁。s
r
s
s
foo
(1) NRVO 表示命名返回值优化。
(2) 步骤3的相关措辞见[expr.call] p6:
是的 实现定义 参数的生存期是在定义参数的函数返回时结束,还是在封闭的完整表达式结束时结束。 每个参数的初始化和销毁发生在出现函数调用的完整表达式的上下文中。
评论
std::string a = foo("42");
a
"42"
std::string s
s