gpt4 book ai didi

c++11 - 值传递和右值传递引用的重载

转载 作者:行者123 更新时间:2023-12-03 21:37:51 25 4
gpt4 key购买 nike

我有一个子例程的两个重载,该子例程采用占用几兆字节动态内存并具有 move 构造函数和赋值运算符的类型的参数:

// Version intended for use when we the caller has 
// deliberately passed an rvalue reference using std::move
void MyClass::setParameter(MyMoveableType &&newParameter)
{
m_theLocalParameter = std::move(newParameter);
}

// Version intended for use when the caller has passed
// some other type of value which shouldn't be moved
void MyClass::setParameter(MyMoveableType newParameter)
{
m_theLocalParameter = std::move(newParameter);
}

意图很明显,第一个重载将 newParameter 的内容从调用 newParameter 对象的子例程链向上 move ,而第二个重载创建 newParameter 的全新副本(或调用复制省略以避免在适当的情况下这样做,例如参数实际上是函数的返回值),然后将副本 move 到本地数据成员中,从而避免进一步复制。

但是,如果我尝试使用第一个重载实际将对象 move 到我的类中:
{
MyClass theDestination;
MyMoveableType theObject
...
// ...Various actions which populate theObject...
...

TheDestination.setParameter(std::move(theObject));
...
}

...然后在我尝试过的每个编译器上,我都会遇到以下错误:
call to member function 'setParameter' is ambiguous

现在我可以看到,将右值引用传递给第二个重载实际上是完全合法的,如果我没有提供第一个重载,这就是我希望编译器做的,而不会发出警告。即便如此,我希望编译器能够完全清楚这段代码的意图是什么,因此我希望它会选择第二个重载作为最佳匹配。

我可以通过重新定义第二个构造函数以获取 const 引用并取消 std::move 来消除错误(尽管这不会是错误
把它留在里面;编译器只会忽略它)。这会正常工作,但我会失去利用复制省略的机会。这可能是
在此特定应用程序的性能方面具有重要意义;讨论中的对象是高分辨率视频帧,以 30
每秒帧数。

在这种情况下,我可以做些什么来消除重载的歧义,从而使我的例程同时具有按值传递和按右值传递引用版本?

最佳答案

The intention is clearly that the first overload moves the contents of newParameter from wherever up the chain of subroutine-calls the newParameter object originated, whilst the second overload creates a brand new copy



这不是你如何做到的。你有两个明智的选择:

方法A

您只编写值重载,然后无论如何都将其移出 - 这意味着您将始终支付构造函数的价格,无论是 move 还是复制。

方法B

你为 (const T&) 写了重载和 (T&&) .这样您就可以复制第一个并使用完美转发跳过第二个中的 move CTOR。

我建议将方法 A 作为默认值,而 B 仅在 c-tor 调用实际上很重要时才推荐。

关于c++11 - 值传递和右值传递引用的重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33021448/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com