想象一下,我有一个类,其主要职责是填充数据容器。我想将数据移出这个类。所以我有:
class cCreator
{
public:
void generate()
{
///generate the content of data_ and populate it
....
....
}
//variation 1
std::vector<int>&& getData1()
{
return std::move(data_);
}
//variation 2
std::vector<int> getData2()
{
return std::move(data_);
}
private:
std::vector<int> data_
};
getData()的变体1和变体2之间的区别是什么。当我省略&amp;&amp;和从函数定义??
答案 0 :(得分:3)
在第一种情况下,函数本身实际上没有移动。您只是返回一个右值引用,它允许原始调用者在需要时移动。在第二种情况下,无论调用者如何使用结果,数据实际上都会被移动到临时数据中。
cCreator c1, c2;
c1.getData1(); // no move
std::vector<int> v1 = c1.getData1(); // move directly from data_
// into v1.
c2.getData2(); // move to temporary, which isn't used.
std::vector<int> v2 = c2.getData1(); // move from data_ to temporary,
// then move from temporary to v2.
答案 1 :(得分:1)
版本1可能是一个坏主意,f(x.getData())
之类的内容可能会移动或不移动,具体取决于f
的签名。一般来说,我们希望任何move
在代码中都是明确的,所以你至少应该有类似的东西:
std::vector<int>&& getData() &&
{
return std::move(data_);
}
所以现在移动必须是明确的:f( std::move(x).getData() )
,你可能想为观察提供const &
的重载。
如果它有另一个名字,那么版本2就没问题了。根据我的经验,99%的人认为getX
是非修改操作。最好称之为releaseData
,这与unique_ptr::release
的命名一致。
答案 2 :(得分:1)
我想在这种特定情况下,其数据被提取(移动)的容器是一个stl向量,std :: swap将是一个有效的选项。所以简单地提供:
const std::vector<int>& getData() const;
std::vector<int>& getData();
woudl使用户能够安全地提取数据,如果他愿意的话。如果由于某种原因C ++ 11不可用,这可能只是可行的选择。