在我的项目中我有这样的功能:
bool VectorList::put(const Pair &p);
这将通过复制 Pair
将 Pair
添加到 VectorList
中。
我可以这样使用它:
Pair p { "key", "value" };
VectorList v;
v.put(p);
// or
v.put(Pair{ "anotherkey", "anothervalue" });
但是在第二种情况下创建了一个不必要的对象,所以我想做
bool VectorList::put(Pair &&p);
我检查了这是如何在 vector (gcc, llvm) 中完成的,两种方法中的代码 100% 相同,除了 equal/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;
}
最佳答案
是的,使用 perfect forwarding :
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;
}
另一种可能性是像 Maxim's answer 那样按值传递.完美转发版本的优点是,如果您传入兼容的参数,它不需要中间转换,并且如果移动成本高,则性能更好。缺点是转发引用函数非常贪婪,因此其他重载可能不会按照您的意愿行事。
请注意,Pair &&p
不是通用引用,它只是一个右值引用。通用(或转发)引用在推导的上下文中需要一个右值,例如模板参数。
关于c++ - 通用引用c++11代码重复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32778314/