C++ 编译器可以对用于返回值的命名 const 变量执行 RVO 吗?

Wil*_*mKF 6 c++ return-value-optimization nrvo c++17

此问题与此处显示的相关问题略有不同。

在 C++17 中,我有一个局部变量,我希望将其设置为 const,以证明它在根据 Scott Meyers effective C++ item 3 建议尽可能使用 const 创建后未经修改

#include <string>

std::string foo()
{
    const std::string str = "bar";

    return str;
}

int main()
{
    std::string txt = foo();
}
Run Code Online (Sandbox Code Playgroud)

即使由于常量差异而导致txt的类型str与 的返回类型不同,编译器是否可以对 执行(命名)返回值优化?foo

Mic*_*zel 7

指定返回值优化是通过 C++17 中[class.copy.elision]中指定的复制省略来启用的。这里的相关部分是[class.copy.elision]/1.1

当满足某些条件时,允许实现省略类对象的复制/移动构造,即使为复制/移动操作选择的构造函数和/或对象的析构函数具有副作用。[…]

  • return具有类返回类型的函数的语句中,当表达式是非易失性自动对象的名称(函数参数或由处理程序的异常声明引入的变量除外([except.handle]) ) 与函数返回类型具有相同的类型(忽略 cv 限定),可以通过将自动对象直接构造到函数调用的返回对象中来省略复制/移动操作

[…]

强调我的。因此,编译器可以在这里执行优化。快速测试似乎可以验证编译器实际上会在这里执行此优化......

请注意,这const可能仍然存在问题。如果编译器不执行复制省略(这里只允许,不保证发生;即使在 C++17 中,因为语句中的表达式return不是纯右值),const通常会阻止对象被移动(通常无法从物体上移动const)...