在保证不调用复制构造函数的 C++ 中,是否有一种从函数返回值的好方法?返回值优化或移动构造函数都可以。例如,使用以下代码
#include <iostream>
struct Foo {
private:
// Disallow the copy and default constructor as well as the assignment
// operator
Foo();
Foo(Foo const & foo);
Foo & operator = (Foo const & foo);
public:
// Store a little bit of data
int data;
Foo(int const & data_) : data(data_) { }
// Write a move constructor
Foo(Foo && foo) {
std::cout << "Move constructor" << std::endl;
data=foo.data;
}
};
// Write a function that creates and returns a Foo
Foo Bar() {
Foo foo(3);
return foo;
}
// See if we can mix things up
Foo Baz(int x) {
Foo foo2(2);
Foo foo3(3);
return x>2 ? foo2 : foo3;
}
int main() {
// This is using the return value optimization (RVO)
Foo foo1 = Bar();
std::cout << foo1.data << std::endl;
// This should make the RVO fail
Foo foo2 = Baz(3);
std::cout << foo2.data << std::endl;
}
编译错误
$ make
g++ -std=c++11 test01.cpp -o test01
test01.cpp: In function 'Foo Baz(int)':
test01.cpp:10:5: error: 'Foo::Foo(const Foo&)' is private
test01.cpp:35:25: error: within this context
make: *** [all] Error 1
因为复制构造函数是私有(private)的。现在,如果我们将 Baz 函数修改为
// See if we can mix things up
Foo Baz(int x) {
Foo foo2(2);
Foo foo3(3);
return std::move(x>2 ? foo2 : foo3);
}
我们确实正确运行。然而,这似乎阻止了 RVO 的使用。如果我们必须保证不调用复制构造函数,是否有更好的方法来构造这些函数?
最佳答案
来自 C++ 标准:
[class.copy]/31: When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the copy/move constructor and/or destructor for the object have side effects. ... This elision of copy/move operations, called copy elision, is permitted in the following circumstances (which may be combined to eliminate multiple copies):
- in a return statement in a function with a class return type, when the expression is the name of a non-volatile automatic object (other than a function or catch-clause parameter) with the same cv- unqualified type as the function return type, the copy/move operation can be omitted by constructing the automatic object directly into the function’s return value
因为 x > 2 ? foo2 : foo3
不是自动对象的名称,不允许复制省略。
关于c++ - 从具有移动语义或返回值优化但不是复制构造函数的函数返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20484153/