假设存在一个可复制且可移动构造(且可分配)的对象,例如std::vector<int>
。我的一类将接受此类对象并将其存储为成员:
class A
{
public:
void SetVector(const std::vector<int>& v) { v_ = v; }
private:
std::vector<int> v_;
};
这将复制用户给定的向量。这是将参数传递给函数的经典C ++方法)
现在,假设用户对将其向量移动到A
类型的对象中感到满意。这样可以避免复制。为此,我们需要一个具有r值引用的成员函数:
class A
{
public:
void SetVector(const std::vector<int>& v) { v_ = v; }
void SetVector(std::vector<int>&& v) { v_ = std::move(v); }
private:
std::vector<int> v_;
};
现在用户可以选择:可以将矢量复制到对象中或进行移动,在这种情况下,将重置原始矢量(在移动后的对象处于任何状态下都可以重置)。
另一方面,我们必须编写两个单独的成员函数才能为用户提供这一选择。当我们拥有大量类似功能时,负担可能会成问题。
似乎有第三种可能性:
class A
{
public:
void SetVector(std::vector<int> v) { v_ = std::move(v); }
private:
std::vector<int> v_;
};
这样,用户可以通过复制左向量的l值参考或通过移动右向量的r值参考来提供向量。
此策略是否有弊端?
也许我没有考虑一些极端情况?
我看到的唯一区别是,第三种方法(按值传递)总会有一个移动操作(一个复制和一个移动或两个移动)。我想编译器无法做很多优化一举一动的事情。假设我很乐意为只使用该功能的一个版本而付出一定的代价,那么这种按值传递方法是个好主意吗?