c++ - 哪个功能结构更好?

标签 c++ c++11 rvalue-reference nrvo

看下面的代码:

class MyClass{
public:
    MyClass(){}
    MyClass(MyClass &&){}
    MyClass(const MyClass &){}
};
MyClass f1(){
    MyClass &&o=MyClass();
    /*...*/
    return std::move(o);//or return static_cast<MyClass &&>(o);
}
MyClass f2(){
    MyClass o=MyClass();
    /*...*/
    return o;
}


int main(int, char **){
    auto a=f1();
    auto b=f2();
}

函数 f2 是返回对象的正常形式。 NRVO可能适用,并且可以避免额外的复制构造函数调用。 f1 是使用右值引用的新形式。对于不支持 NRVO 但支持右值引用的系统,调用移动构造函数而不是复制构造函数,这在大多数情况下会被认为更好。

f1 的问题在于:在这种情况下是否有支持 NRVO 的编译器?这似乎是 future 更好的形式。

最佳答案

are there any compiler support of NRVO in this case?

定义“编译器支持”?

f1 所做的是完全破坏编译器优化MyClass 拷贝的能力。让我们详细看看f1

MyClass &&o=MyClass();

这会创建一个临时,而不是堆栈变量。然后将该临时对象绑定(bind)到名为 o 的右值引用,这将临时对象的生命周期延长到函数结束。

return std::move(o); //or return static_cast<MyClass &&>(o);

这将返回一个堆栈绑定(bind)右值引用的右值引用到一个临时值。由于您返回的是一个值,而不是一个引用,因此编译器必须从中创建一个临时值。

将临时文件复制/移动到 a 中将被省略。但是您仍然创建了两个临时值(原始值和返回值)。

因此 f1 执行以下操作:

create temporary
copy/move from temporary to return value
elide copy/move from return value to `a`.

f2 做:

create stack variable
elide copy/move from stack variable to `b`.

如果 NVRO 不存在,你有:

create stack variable
copy/move from stack variable to return value
elide copy/move from stack variable to `b`.

所以,f2 在最坏的情况下等于f1。更有可能,更好。

请停止试图超越编译器。让复制省略完成它的工作。

关于c++ - 哪个功能结构更好?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7898395/

相关文章:

c++ - 我是否必须手动实现比较运算符的交换性?

c++ - unique_ptr 与 vector : error: call to implicitly-deleted copy constructor of XXX

c++ - 普通的右值引用和 std::forward 返回的有什么区别?

C++计时: Get seconds with a precision of 3 decimal places

c++ - 带有 C++11 线程的 Qtcreator

c++ - 如何在进入函数之前指定需要什么互斥锁

c++ - 使用右值的比较函数

c++ - 对引用引用的函数的直观理解

c++ - 源文件中的嵌套类定义

C++,数组大小必须是一个常量表达式