explicit
关键字建议用于可以接受一个参数的所有大多数构造函数,但不包括拷贝构造函数。
对于拷贝构造函数,它有一定的用途(禁止通过函数调用、返回等方式进行隐式复制),但这通常并不是所需的。
那么移动构造函数呢?有什么合理的使用情况使它们变得显式吗?在这里应该遵循什么样的最佳实践?
explicit
关键字建议用于可以接受一个参数的所有大多数构造函数,但不包括拷贝构造函数。
对于拷贝构造函数,它有一定的用途(禁止通过函数调用、返回等方式进行隐式复制),但这通常并不是所需的。
那么移动构造函数呢?有什么合理的使用情况使它们变得显式吗?在这里应该遵循什么样的最佳实践?
显式
的移动构造函数可能会影响与标准算法等的兼容性。例如,std::swap<T>
要求T
是可移动构造的。而可移动构造是根据一个表达式来指定的,即T u = rv;
(其中rv
是类型为T
的右值)。T u = rv;
就无效了,这种类型不能与std::swap
一起使用。(但在这个特定实例中,可以通过专门化std::swap
来提供所需的功能,例如使用T u(rv);
)。unique_ptr<T, D>
的删除器bind
中使用的调用包装器(涉及传递的所有衰减类型)thread
、async
、call_once
(都是以调用包装器作为指定方式)sort
、stable_sort
、nth_element
、sort_heap
大多数情况下,您可能希望使用隐式移动构造函数。它们通常与拷贝构造函数属于相同的类别。不是所有的单参数构造函数都建议使用显式构造函数,但大多数情况下建议使用。移动构造函数不在该列表中。
explicit
关键字,以避免意外的转换发生。
复制构造函数和移动构造函数在这个意义上并不容易“令人惊讶”。它们通常发生在预期的位置。如果您不想要它们,我希望它们被标记为 =delete
而不是显式声明。
T([const] [volatile] T&)
。参见12.8/2。T(int)
是一个可以用一个参数调用的构造函数,但不是复制构造函数,因为它不会“复制”一个T
的实例。 - Steve Jessopexplicit
关键字会对这样的构造函数产生影响吗?你能举个例子吗? - Kos