c++ - 由于右值引用,函数的双重定义

标签 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 定义中的内容,并为右值引用重载 我希望我只需要复制 vector 中的元素,因此不需要引用,但是 std::Vector::push_back 被定义为通过引用获取参数,请参阅:http://www.cplusplus.com/reference/vector/vector/push_back/

所以这就是困扰我的地方,我总是必须双重复制我的函数以符合引用参数行为(在这种情况下为 std::Vector::push_back)

我不能使用 const aClass&,因为如果我使用临时对象来调用我的函数,我的 vector 迭代器将指向已被删除的内容

最佳答案

如果 sf::ConvexShape 是廉价移动的,只需提供一个通过复制获取的重载:

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

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

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

  • 从你的函数内部到vector,你只需付出一步;
  • 如果调用者传递给你一个它仍然感兴趣的对象,他会按原样传递它,所以它会被复制——但只有一次,这是一个你无论如何都会做的复制,将它放入 vector ;
  • 如果调用者向您传递一个他无论如何都不需要的对象,他会执行 addShape(std::move(sShape)),这只会支付两次移动。

相反,如果你有一个左值和一个右值引用重载,你甚至可以在移动时更加便宜(在上面的情况下你避免了一次移动),但在 99% 的情况下,这只是一个无用的并发症,导致代码重复,因为无论如何移动都应该是几乎免费的。

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

关于c++ - 由于右值引用,函数的双重定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48130940/

相关文章:

c++ - 从 engOpen(..) 启动 matlab,被通知引擎被关闭

c++ - 通过引用返回静态 vector 很慢

关于错误 : lvalue required as unary '&' operand 的困惑

javascript - 如何继续 'if' 语句来比较多个函数返回值作为参数?

string - 类型 "string"和 "func() string"之间有什么区别?

c++ - 具有 std::minmax 和右值的结构化绑定(bind)

c++ - 当 STL 容器对象的值不可复制构造时,如何将其附加/复制到另一个对象,例如标准::线程

c++ - 我该如何做类似 if(2 variables) 的事情?

C++ std::stringstream 到 const char* 的转换

javascript - 这段 JavaScript 代码有什么问题吗?