2

考虑以下情况,其中一些内容通过多个层添加到向量中:

class A {
public:
  void Add(Content c) {
    // Considerable amount of checking code here.
    v.push_back(c);
  }
private:
  std::vector<Content> v;
};

class B {
public:
  void Add(Content c) {
    // Considerable amount of additional code here.
    a.Add(c);
  }
private:
  A a;
};

class C {
public:
  void Add(Content c) {
    // Considerable amount of additional code here.
    b.Add(c);
  }
private:
  B b;
};

这可以继续,但你在这里看到了重点。我希望通过复制或移动添加内容,即通过 push_back(const Content&) 或 push_back(Content&&)。调用者应该能够调用:

C c;
Content z;
c.Add(z);

或者

c.Add(move(z));

并获得最少数量的副本。

有没有一种方法可以在不重复附加代码且不使用 Add functions 模板函数的情况下实现这一点?

4

2 回答 2

2

为右值和左值重载两种方法是一种方法:

void Add(const Content & c);
void Add(Content && c);

使用完美转发可以避免两次重载。您应该使所有add方法都像这样:

template<typename T>
void add(T&& a)
{
   b.Add(std::forward<T>(a));
}

 

另一种更好的方法(IMO)是Content可移动的。如果Content是真正的类(不是模板的占位符),你可以这样做:

class Content
{
public:
  Content(const Content &);
  Content(Content &&);

  Content &operator=(Content);  // Copy and swap idiom!

  ~Content();
};

之后,您可以重写Add如下方法:

 void Add(Content c) {
    b.Add(std::move(c));
          ^^^^^^^^^^^^
 }

这种方法的优点是,您可以从调用方透明移动或复制。

于 2013-10-12T16:08:41.417 回答
0

您可以使用下一个签名添加两种方法:

void Add(Content && c);
void Add(Content & c);

其他选项是通用参考,但您需要模板。

于 2013-10-12T15:58:38.327 回答