如果我有一个实现移动语义的类:
class BigObject
{
public:
BigObject(something x = something()) { ... }
BigObject(const BigObject& other) { ... }
BigObject(BigObject&& other) { ... }
BigObject& operator=(BigObject other) { ... }
void swap(BigObject& other) { ... }
// [...]
};
auto begin = std::begin(somethingSequence); // collection doesn't matter here
auto end = std::end(somethingSequence); // collection doesn't matter here
BigObjectOutputIterator dest; // collection doesn't matter here
在lambda中返回BigObject的正确方法是什么?
std::transform(begin, end, dest,
[](something x) -> BigObject {return BigObject(x); });
或
std::transform(begin, end, dest,
[](something x) -> BigObject&& {return std::move(BigObject(x)); });
或
std::transform(begin, end, dest,
[](something x) -> BigObject {return std::move(BigObject(x)); });
或其他形式?
感谢。
答案 0 :(得分:6)
第一个和第三个表单基本相同,因为return BigObject(x);
是一个右值,因此已经调用了移动构造函数。
然而,第二种形式会调用未定义的行为,因为右值引用仍然只是一个引用,对超出范围的内容的引用仍然像以前一样糟糕。
答案 1 :(得分:3)
第一种形式就好了。作为一般规则,永远永远,返回右值引用。第三种形式不需要移动,因为BigObject(x)
已经是右值。