通用引用c ++ 11代码重复

Nic*_*ick 2 c++ dry c++11 universal-reference

在我的项目中,我的功能如下:

bool VectorList::put(const Pair &p);
Run Code Online (Sandbox Code Playgroud)

这通过复制添加Pair到.VectorListPair

我可以像这样使用它:

Pair p { "key", "value" };

VectorList v;
v.put(p);

// or
v.put(Pair{ "anotherkey", "anothervalue" });
Run Code Online (Sandbox Code Playgroud)

但是在第二种情况下会创建一个不必要的对象,所以我想这样做

bool VectorList::put(Pair &&p);
Run Code Online (Sandbox Code Playgroud)

我检查了如何在vector(gcc,llvm)中完成此操作,并且在两个方法中都有100%相同的代码,除了等于/ std :: move()行.

有没有办法在没有代码重复的情况下做到这一点?


put() 看起来与此类似:

struct Node{
    Pair pair;
    AdditionalThings at;
};

bool VectorList::put(const Pair &p){
    if (not_good_for_insert(p))
         return false;
    // ...
    Node node = create_node();
    node.pair = p;
    // ...
    return true;
}
Run Code Online (Sandbox Code Playgroud)

Tar*_*ama 7

是的,使用完美转发:

template <typename P>
bool VectorList::put (P &&p) {
    //can't forward p here as it could move p and we need it later
    if (not_good_for_insert(p)) 
     return false;
    // ...
    Node node = create_node();
    node.pair = std::forward<P>(p);
    // ...
    return true;
}
Run Code Online (Sandbox Code Playgroud)

另一种可能性就是像Maxim的回答一样传递价值.完美转发版本的优点是,如果传入兼容的参数,它不需要中间转换,如果移动费用昂贵,则表现更好.缺点是转发引用函数非常贪婪,因此其他重载可能无法按您的意愿行事.

请注意,这Pair &&p不是通用引用,它只是一个右值引用.通用(或转发)引用需要在推导的上下文中使用rvalue,例如模板参数.