bar*_*-md 1 c++ casting reference perfect-forwarding c++11
我正在研究 C++ 中的完美转发机制,我对该std::move()功能有一些疑问。这是一个可能的实现:
template<class T>
typename remove_reference<T>::type&&
std::move(T&& a) noexcept {
typedef typename remove_reference<T>::type&& RvalRef;
return static_cast<RvalRef>(a);
}
Run Code Online (Sandbox Code Playgroud)
当在 上使用时std::unique_ptr<>,此函数将资源的所有权从一个指针转移到另一个指针。我发现这个函数的焦点是从左值引用到右值引用到推导T类型的转换。
#include <iostream>
#include <memory>
using namespace std;
int main() {
unique_ptr<int> p1(new int(20));
unique_ptr<int> p2;
unique_ptr<int> &r = p1;
cout << "p1 = " << p1.get() << endl;
cout << "p2 = " << p2.get() << endl;
// These 2 instructions produce the same effect (then consider just one of them).
p2 = static_cast<unique_ptr<int>&&>(r);
//p2 = move(p1);
cout << "p1 = " << p1.get() << endl;
cout << "p2 = " << p2.get() << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
p1 = 0x467b10
p2 = 0
p1 = 0
p2 = 0x467b10
Run Code Online (Sandbox Code Playgroud)
我想知道当我从 L 引用转换为 R 引用std::unique_ptr<int>类型时会发生什么。
std::move不动,std::forward不前进。
move只是将一种引用转换为另一种引用。它接受一个引用,并返回对相同数据的右值引用。这在运行时什么都不做。移动的是消耗这个右值引用的代码。
该代码现在被告知“像对待临时未命名对象一样对待它”(不完全,但接近)。最常见的消费者是“移动构造函数”或“移动赋值”,这就是实际移动的内容unique_ptr。
至于forward,它是一个有条件的移动,定义为使用一种称为“完美转发”和/或“通用引用”的技术。它有时会移动,有时什么也不做。之所以提,是因为我上面引用的一句精辟的说法提到了:那是另外一个话题。