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



这个问题在此处显示的相关问题上是一个轻微的变体。

在C 17中,我有一个局部变量,我想成为const以证明它在每个Scott Meyers 有效C 项目3时都没有修改的建议,请在可能的情况下使用const:

#include <string>
std::string foo()
{
    const std::string str = "bar";
    return str;
}
int main()
{
    std::string txt = foo();
}

编译器可以针对txt执行(命名(返回值优化,即使str的类型与foo的返回类型不同?

命名的返回值优化由[class.copy.elision]中的C 17中指定的复制elision启用。这里的相关部分是[class.copy.elision]/1.1:

满足某些标准时,即使选择用于复制/移动操作的构造函数和/或对象的驱动器具有副作用,也允许实现省略类对象的复制/移动构造。[&Hellip;]

  • 在具有类返回类型的函数中的 return语句中,当表达式是非挥发性自动对象的名称时(除了函数参数或由处理程序的异常删除引入的函数参数或变量以外(除外[除外。li>

[&hellip;]

强调我的。因此,允许编译器在此处执行优化。快速测试似乎可以验证编译器实际上将在此处执行此优化;

请注意,const仍然有问题。如果编译器不执行复制责任(仅允许,不能保证在这里发生;即使在C 17中,由于return语句中的表达式不是Prvalue(,const通常会防止对象从中移动(通常无法从const对象移动(&Hellip;

同意迈克尔·肯泽尔(Michael Kenzel(的回答。但是有一些具有编译器优化的特点。如果您在没有优化的情况下查看一个简单的示例,则可以看到MSVC编译器的功能-https://godbolt.org/z/b7z6n1ymf

没有优化,MSVC将产生对象的副本而不是NRVO。在某些情况下,这可能很重要。

最新更新