由于右值引用而对函数进行双重定义

double definition of function because of rvalue reference

本文关键字:定义 函数 于右值 引用      更新时间:2023-10-16

所以我的问题是这样的:

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

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

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

如果sf::ConvexShape是廉价的,只需通过复制提供单个重载:

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

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

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

相反,如果你有一个左值和一个右值引用重载,即使在移动周围你也可能非常便宜(在上面的情况下,你可以避免一次移动),但在 99% 的情况下,这只是一个无用的复杂性,导致代码重复,因为无论如何移动都应该几乎是免费的。

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