在填充成员向量期间避免复制构造函数

时间:2017-09-27 15:56:47

标签: c++ c++14 move-semantics

我有一个班级A

class A {
  int value1;
  int value2;
  std::string text;

public:
  A(int value1, int value2, std::string text) 
   : value1(value1), value2(value2), text(text) { }
};

还有一些"容器"班B

class B {
  std::vector<A> objects;
  ...

public:
  ...
  void addObject(A a) {
    objects.push_back(a);
  }
};

代码:

B b;
A a(2, 5, "test");
b.addObject(a);
//I no longer need a from now on

我的问题是,如何优化B::addObject(A a)以避免任何复制。我想要实现的是通过A方法将B.objects类型的新对象添加到B

2 个答案:

答案 0 :(得分:5)

这个问题有很多答案。您只需将B功能更改为move(),将move()更改为该功能:

void addObject(A a) { objects.push_back(std::move(a)); }

b.addObject(std::move(a)); // two moves

你可以通过const lvalue reference和rvalue reference

添加addObject的重载
void addObject(A const& a) { objects.push_back(a); }
void addObject(A&& a) { objects.push_back(std::move(a)); }

b.addObject(std::move(a)); // one move

您可以为addObject添加一个功能模板:

template <class... Args>
void addObject(Args&&... args) { objects.emplace_back(std::forward<Args>(args)...); }

b.addObject(2, 5, "test"); // zero moves

无论哪种方式,这里都有一个完全不必要的副本:

A(int value1, int value2, std::string text) 
: value1(value1), value2(value2), text(text) { }

你想要:

A(int value1, int value2, std::string text) 
: value1(value1), value2(value2), text(std::move(text)) { }

答案 1 :(得分:1)

您可以更改addObject的参数类型并使用emplace_back,以避免构建A的对象,该对象稍后将被使用并将其复制到{{ 1}}。 e.g。

vector

void addObject(int value1, int value2, std::string text) {
  objects.emplace_back(value1, value2, text);
}