https://github.com/watchpoints/daily-interview/issues/25
they’re the foundation on which move semantics and perfect forwarding are built.
https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers
右值引用是将这两个完全不同的特征联系在一起的粘合剂。
它是使移动语义和完美转发成为可能的底层语言机制。
我不会直接解释什么是右值引用。
相反,
我将从要解决的问题开始, 然后展示右值引用如何提供解决方案。
这样,右值引用的定义对您来说就会显得合理和自然。
右值引用至少解决了两个问题:
I will not jump right in and explain what rvalue references are. Instead, I will start with the problems that are to be solved and then show how rvalue references provide the solution.
Rvalue references solve at least two problems:
画外音:
您将了解 std::move 和 std::forward 的使用约定。你会对“type&&”的含糊不清的性质感到舒服,
type&& 本质是什么,回答到问题,右值引用是什么?
The construct “type&&” doesn’t always represent an rvalue reference.
the parameter w is an lvalue
void f(Widget&& w); the parameter w is an lvalue, even though its type is rvalue-reference-to-Widget
It’s especially important to remember this when dealing with a parameter of rvalue reference type, because the parameter itself is an lvalue:
c++能定义引用的引用吗?答案是:不能。
不过你可以补充说:不过有两个例外:类型别名和模板参数时可以间接定义引用的引用。https://www.zhihu.com/question/28023545
c++11支持reference collapse,就是:
& &=>&
&& & =>&
& &&=>&
&& &&=>&&
画外音:
正确的说法是“引用折叠”而其实引用折叠后依旧是普通的引用或者右值引用,
所以其实“引用的引用”严格来说是不存在的。
c++需要引用折叠的原因是为了实现std::move。也就是说,
所谓“引用的引用”的存在价值,只是为std::move、std::forward等而服务的,
小思考:
引用就是指针,二级指针 二级引用 可以等价理解吗?
Effective Modern C++, Chapter 5, Item 28: Understand reference collapsingYou are forbidden from declaring references to references, but compilers may produce them inparticular contexts.
You might expect T&& to only bind to rvalues, because at first glance, it looks like an rvalue reference.
As it turns out though, T&& also binds to lvalues:
template<typename T>
void foo(T&& param)
{
cout<< param <<endl;
}
void tet_foo()
{
int a=27;
foo(a) ; // x is lvalue, so T is int& param's type is also int&
foo(27); // 27 is rvalue, so T is int param's type is therefore int&&
}
画外音:类型推导功能
Here, the following apply:
这里讨论不是智能指针是如何实现和设计的,讨论是如何使用的 make_unique从这里开始
//提问1. unique_ptr能不能相互赋值, //提问2. unique_ptr 如何解决?//提问3。unique_ptr 有什么后果
std::unique_ptr<int> foo ;
std::unique_ptr<int> bar;
//bar = foo;
// unique_ptr& operator=(const unique_ptr&) = delete;
//为什么这个成立呢
foo = std::unique_ptr<int>(new int (101)); // rvalue
//为什么这个成立呢
bar = std::move(foo); // using std::move
//为什么这个成立呢
std::unique_ptr<int> up3 = std::make_unique<int>(3);
// This has been tested with:
// - MSVC 11.0 (Visual Studio 2012)
// - gcc 4.6.3
// - Xcode 4.4 (with clang "4.0")
template <class _Ty, class... _Types, enable_if_t<!is_array_v<_Ty>, int> = 0>
_NODISCARD unique_ptr<_Ty> make_unique(_Types&&... _Args) { // make a unique_ptr
return unique_ptr<_Ty>(new _Ty(_STD forward<_Types>(_Args)...));
}
/// std::make_unique for single objects
template<typename _Tp, typename... _Args>
inline typename _MakeUniq<_Tp>::__single_object
make_unique(_Args&&... __args)
{ return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...));