楼主这个例子,是说不要给充当返回值的变量加上个const吧,因为没有const,那么在NRVO时就可以执行move(前提是有move ctor,不管是编译器提供的,还是码农提供的),并且最后有可能把move也给优化掉。
返回的是值的话,实测有没const都一样
可以搞个demo程序,看看这几种情况下编译器是怎么优化的
https://en.cppreference.com/w/cpp/language/copy_elision (注意尾部的bug列表,是说const表达式不允许NRVO但要强制执行copy elision)
class MyClass {
public:
MyClass() { printf("default ctor\n"); }
MyClass(const MyClass &rhs) {
if (this != &rhs) {
s = rhs.s;
}
printf("copy ctor\n");
}
MyClass(MyClass &&rhs) {
if (this != &rhs) {
s = std::move(rhs.s);
}
printf("move ctor\n");
}
~MyClass() { printf("dtor\n"); }
private:
std::string s;
};
MyClass Test1() {
printf("Test1\n");
MyClass obj;
return obj;
}
MyClass Test2() {
printf("\nTest2\n");
const MyClass obj;
return obj;
}
MyClass Test3() {
printf("\nTest3\n");
MyClass t;
MyClass &&obj = std::move(t);
return obj;
}
MyClass Test4() {
printf("\nTest4\n");
MyClass obj;
return std::move(obj);
}
class MyClass2 {
public:
MyClass2() : a{0} { printf("default ctor\n"); }
MyClass2(const MyClass2 &rhs) {
a = rhs.a;
printf("copy ctor\n");
}
MyClass2(MyClass2 &&rhs) = delete;
~MyClass2() { printf("dtor\n"); }
private:
int a;
};
MyClass2 Test5() {
printf("\nTest5\n");
const MyClass2 obj;
return obj;
}
// 这个编译不过去,没有move ctor,导致NRVO搞不下去。编译器也并没调用copy ctor
MyClass2 Test6() {
printf("\nTest6\n");
MyClass2 obj;
return obj;
}
// 返回局部变量的引用是错误的。只是演示。
const MyClass2 & Test7() {
printf("\nTest7\n");
const MyClass2 obj;
return obj;
}
int main() {
{ auto a1 = Test1(); }
{ auto a2 = Test2(); }
{ auto a3 = Test3(); }
{ auto a4 = Test4(); }
{ auto a5 = Test5(); }
//Test6();
{ auto a7 = Test7(); }
}
Test1
default ctor
dtor
Test2
default ctor
dtor
Test3
default ctor
move ctor
dtor
dtor
Test4
default ctor
move ctor
dtor
dtor
Test5
default ctor
dtor
Test7
default ctor
dtor
copy ctor
dtor
※ 修改:·z16166 于 Sep 18 15:34:36 2022 修改本文·[FROM: 114.254.46.*]
※ 来源:·水木社区
http://www.mysmth.net·[FROM: 114.254.46.*]
修改:z16166 FROM 114.254.46.*
FROM 114.254.46.*