建议对
all
explicit
关键字,这些构造函数可以用一个参数调用,复制构造函数除外。
对于复制构造函数,它有一个用途(禁止通过函数调用、返回等进行隐式复制),但这不是通常想要的。
移动构造函数怎么样?是否有任何合理的用例可以使它们变得明确?这里有什么好的做法?
explicit
移动构造函数可能会影响与例如的兼容性标准算法。例如,std::swap<T>
要求T
可移动构造。反过来,MoveConstructible 是根据表达式指定的,即 T u = rv;
(其中 rv
是 T
类型的右值)。
如果给定类型既没有非显式复制构造函数,也没有非显式移动构造函数,则
T u = rv;
无效,并且该类型不能与 std::swap
一起使用。 (然而,在这种特殊情况下,可以专门化 std::swap
来提供所需的功能,例如通过使用 T u(rv);
)。
更简单地说,
explicit
移动或复制构造函数违背了预期,并且不能与通用代码一起使用。
标准库的其他一些部分提出了 MoveConstructible 要求:
unique_ptr<T, D>
bind
(所有传递的衰变类型都涉及)thread
、async
、call_once
(全部以调用包装器形式指定)sort
、stable_sort
、nth_element
、sort_heap
您可能需要一个隐式移动构造函数来满足大多数用途。它们通常与复制构造函数属于同一类别。不建议对 all 单参数构造函数使用显式,但建议大多数人使用显式。移动构造函数不在该列表中。
建议将
explicit
关键字用于(单参数)converting 构造函数,以避免在意外位置发生意外转换。
从这个意义上来说,复制构造函数和移动构造函数并不“令人惊讶”。它们大部分发生在预期的地方。如果您不想要它们,我希望它们被标记为
=delete
,而不是明确表示。
真正的问题是如何使用显式移动构造函数?它无法在右值上调用,因此编译器必须始终选择复制构造函数(如果可用),否则无法编译。
编辑:这里是示例的链接:http://www.ideone.com/nm7KM
从函数按值返回时,隐式移动构造函数通常可以使过程更加高效。