28

The explicit keyword is recommended for all most constructors which can be called with one argument, except for copy constructors.

For copy constructors, it has an use (to forbid implicit copying via function call, return, etc), but it's not what's usually wanted.

What about move constructors? Is there any reasonable use case to make them explicit? What's the good practice here?

4

5 回答 5

27

explicit移动构造函数会影响与例如标准算法的兼容性。例如,std::swap<T>要求它T是 MoveConstructible。反过来,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
于 2011-07-20T08:29:42.267 回答
5

对于大多数用途,您可能需要一个隐式移动构造函数。它们通常与复制构造函数属于同一类别。不建议对所有单参数构造函数使用显式,但建议对大多数构造函数使用。移动构造函数不在该列表中。

于 2011-07-20T08:13:06.303 回答
5

建议将explicit关键字用于(单参数)转换构造函数,以避免在意想不到的地方发生令人惊讶的转换。

从这个意义上说,复制构造函数和移动构造函数并不“令人惊讶”。它们主要发生在预期的地方。如果您不想要它们,我希望它们被标记=delete而不是明确显示。

于 2011-07-20T12:21:41.213 回答
2

实际的问题是如何使用显式移动构造函数?它不能在右值上调用,因此编译器必须始终选择一个复制构造函数(如果可用),否则编译失败。

编辑:这里是示例的链接:http ://www.ideone.com/nm7KM

于 2011-07-20T17:08:15.537 回答
0

从函数按值返回时,隐式移动构造函数通常可以使过程更高效。

于 2012-04-30T16:30:35.723 回答