unique_ptr c++ 03仿真中的move函数
The move function in unique_ptr C++03 emulation
我试图理解c++ 03仿真unique_ptr是如何实现的。Unique_ptr很像std::auto_ptr,但更安全。当auto_ptr隐式地(即静默地)转移所有权时,它会抛出编译器错误。例如,一个简单的赋值。move
函数是仿真unique_ptr安全的关键。
问题:
- 为什么有三个移动函数?
-
第三个move函数接受引用并将其转换为右值,实现(简化)如下。
T move(T &t) { return T(detail_unique_ptr::rv<T>(t)); }
在上面的代码中,显式转换为T似乎是不必要的。事实上,Visual Studio 2010在没有显式转换为t的情况下是非常完美的。
T move(T &t) {
return detail_unique_ptr::rv<T>(t);
}
然而,g++、clang、Comeau都不喜欢第二个版本。这些编译器抱怨没有unique_ptr<T>
的构造函数将detail_unique_ptr::rv<T>
作为参数。为什么呢?unique_ptr已经定义了一个(非显式的)构造函数,它将detail_unique_ptr::rv<T>
作为参数。为什么这个不是自动拾取的?
原因是,如果不进行用户定义的转换(将右值传递给unique_ptr的接受rv的构造函数,就不能用另一个unique_ptr 初始化一个unique_ptr。然而,当没有显式调用unique_ptr
的ctor(如unique_ptr(...)
)时,您执行复制初始化,在您的情况下,它首先成功地构造了一个右值临时unique_ptr,但随后无法将该临时复制到返回值目标对象中,因为在该复制中,不允许用户定义的转换(这也被称为原则规则"初始化中没有两个用户定义的转换")。Msvc允许副本使用接受非const unique_ptr引用的函数,这是非标准的。
从同一类的对象复制类初始化时,不需要这样的两步初始化。源对象只是被传递给unique_ptr
的非显式构造函数,后者将使用rv-taking构造函数将源对象转换为rv
,并通过这种方式成功地构造返回值目标对象。
出于同样的原因,没有从unique_ptr<Derived>
到unique_ptr<Base>
的隐式转换。在第一步中,将成功创建unique_ptr<Base>
,但是当将该临时对象复制到unique_ptr<Base>
目标对象时,不能使用任何用户定义的转换的限制阻止了成功。
- 瓦尔格林德:数学函数"Conditional jump or move depends on uninitialised value(s)"
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 返回一个带有 std::move 的对象并链接函数
- 添加自定义析构函数时,Move 构造函数在派生类中消失
- 将向量从 N1 缩小到 N2 项,而不触发默认构造函数并仅使用 move 语义
- 为什么 std::move 不将默认移动构造函数中的源变量更改为默认值?
- 复制elision、std::move和链式函数调用
- std::映射,只有move构造函数可用
- 为什么我的代码中没有调用move构造函数
- std::转换move构造函数的模板专业化的变体
- std::tuple默认构造函数,带有move可构造元素
- 使用 std::move 将参数传递给函数,如果该参数声明为按值传递或使用移动操作数 &&,是否有区别?
- 如何调用move构造函数
- 复制初始化:为什么即使关闭了复制省略,也没有调用move或copy构造函数
- 为什么我们需要在构造函数的初始化列表中使用 std::move?
- 在构造函数中初始化成员时,是否应该在成员上使用 std::move?
- 我可以将 std::move 与不提供 move 构造函数的类一起使用吗?
- 在C中实现C++标准11的std::move函数
- unique_ptr c++ 03仿真中的move函数
- 为什么当定义析构函数时,编译器不再添加默认的move函数和赋值函数