假设我有一个带有复制构造函数和移动构造函数的对象“foo”,以及一个函数
foo f() {
foo bar;
/* do some work */
return bar;
}
该标准似乎声明编译器将尝试执行以下操作:NRVO,按右值返回 ref,按值返回,失败;以该顺序。
有什么方法可以强制编译器永远不会按值返回,因为我的复制构造函数非常昂贵?
假设我有一个带有复制构造函数和移动构造函数的对象“foo”,以及一个函数
foo f() {
foo bar;
/* do some work */
return bar;
}
该标准似乎声明编译器将尝试执行以下操作:NRVO,按右值返回 ref,按值返回,失败;以该顺序。
有什么方法可以强制编译器永远不会按值返回,因为我的复制构造函数非常昂贵?
编译器会尝试做:NRVO,按右值返回 ref,按值返回,失败;以该顺序。
上面的措辞不准确,可能表明您有误解。编译器可以使用 NRVO(大多数会),如果不可用,它将始终按值返回,不同之处在于返回值的构造方式。如果您的类型具有移动构造函数,编译器必须使用该构造函数,并且只有在您的类型没有移动构造函数时才会使用复制构造函数。
也就是说,如果您的类型具有移动构造函数,则使用复制构造函数的编译器将不符合 C++11。
foo
如果有一个有效的移动构造函数,您的代码将永远不会通过副本返回。
您还可以使用输出参数而不是返回:
void f(foo& bar) { ... }
但实际上所有编译器都会做NVRO。