由于rvalue引用而导致函数的双重定义

时间:2018-01-06 19:16:07

标签: c++ function rvalue

所以我的问题是:

我的.h

中有什么
class PlayerClass
{
//Class declaration
//...
std::vector<sf::ConvexShape> parts;

void addShape(sf::ConvexShape& sShape);
void addShape(sf::ConvexShape&& sShape);
}; 

我的.cpp

中有什么
void PlayerClass::addShape(sf::ConvexShape& sShape)
{
    //processing
    //...

    parts.push_back(sShape);
}
void PlayerClass::addShape(sf::ConvexShape&& sShape)
{
   //processing
   //...

   parts.push_back(sShape);
}

此时,我必须复制粘贴我PlayerClass::addShape定义中的内容并重载rvalue引用 我希望我只需要在向量中复制元素,因此无需参考,但std::Vector::push_back被定义为通过引用获取参数,请参阅:http://www.cplusplus.com/reference/vector/vector/push_back/

这就是困扰我的事情,我总是要复制我的函数以符合参考参数行为(在这种情况下为std::Vector::push_back

我不能使用const aClass&,因为如果我使用临时对象来调用我的函数,我的向量迭代器会指向已被删除的东西

1 个答案:

答案 0 :(得分:1)

如果sf::ConvexShape可以便宜地移动,只需通过复制提供一次过载:

void PlayerClass::addShape(sf::ConvexShape sShape)
{
    //processing
    //...

    parts.push_back(std::move(sShape));
}

这涵盖了所有情况,但开销可以忽略不计:

  • 从你的函数内部到向量,你只需付出一个动作;
  • 如果调用者正在传递一个它仍然感兴趣的对象,他将按原样传递它,因此它将被复制 - 但只需复制一次,这是一个副本你无论如何都会把它放到它进入矢量;
  • 如果来电者正在传递一个他无论如何都不需要的物体,他就会做addShape(std::move(sShape)),这只会支付两次动作。

如果你有一个左值和一个右值参考超载就像你做的那样,你甚至可以在移动时更加便宜(在上述情况下你可以避免一次移动),但在99%的情况下,它只是一个无用的导致代码重复的复杂化,因为无论如何,移动预计几乎是免费的。

在大多数处理可移动类型的代码中,如果你最终想拥有一个副本,那么参数是正确的 - 理想情况下,你不希望在移动构造函数之外看到一个右值引用参数。