我什么时候应该提供移动感知过载?

时间:2014-05-29 07:40:06

标签: c++ c++11 move-semantics

如果我有一个管理一些动态内存的类(例如矢量类型)并且它已经有一个移动构造函数,为函数提供移动感知重载是否有意义,或者是否会移动 - 构造师会照顾它吗?

例如,我应该使用Class&&变量重载哪些(如果有的话):

// the move-aware overload for all of these would be
// void FuncX(Class&&);

void Func1(Class);

void Func3(Class&); // doesn't make a local copy
void Func4(Class&); // makes a local copy

void Func5(Class const);

void Func7(Class const&); // doesn't make a local copy
void Func8(Class const&); // makes a local copy

他们中的任何一个都失去了优化机会,因为我没有提供移动感知变体吗?

2 个答案:

答案 0 :(得分:5)

Func1Func5具有相同的签名,并且已经“移动感知”,因为可以使用左值或右值调用它们,并且可以在传递右值时构造参数。

目前无法使用rvalues调用

Func3Func4,使用Func(Class&&)重载它们将是语义的重大变化,而不仅仅是优化。

Func7已经可以用rvalues调用,没有什么可以通过复制或移动来初始化,重载它将毫无意义。

可以使用rvalues调用

Func8但执行副本,将该函数更改为Func8(Class)将使用副本或移动初始化参数,具体取决于是使用左值还是右值调用它。或者,使用Func8(Class&&)重载它也可以让你在传递右值时避免复制,但现在你有两个要维护的函数。

答案 1 :(得分:3)

首先,当然,你不应该为移动意识而烦恼 过载直到分析器显示它是必要的;它的 额外的复杂性,除非它,否则不应该引入 有必要的。

然而,假设分析器确实显示了复制 一个重大的开销:

Func1(和Func5,签名相同):这个 违反了大多数编码指南(即传递类对象) 参考const); 如果你使用这个签名,它就是 可能是因为您需要参数的唯一副本。移动 语义将给你一个独特的副本,所以他们可能会 合适的。

Func2Func3暗示您要修改 客户的对象。所以你需要访问客户端的对象, 移动语义不会给你。

Func7Func8是常见的情况。如果你只是 访问,而不需要自己存储副本,没有 指向移动语义;它可能会稍微慢一些 而不是对const的引用。如果您要存储副本, 然后移动语义可以产生显着的差异。