3 回答
TA贡献1796条经验 获得超10个赞
C+03引用(在C+11中现在称为lvalue引用)的最大区别是,它可以像临时的那样绑定到rvalue,而不必是Const。因此,这个语法现在是合法的:
T&& r = T();
rvalue参考主要提供以下内容:
移动语义..现在可以定义一个移动构造函数和移动赋值操作符,它接受一个rvalue引用,而不是通常的const-lvalue引用。迁移功能类似于副本,只是它没有义务保持源不变;实际上,它通常修改源,使其不再拥有移动的资源。这对于消除无关的副本是很好的,特别是在标准库实现中。
例如,复制构造函数可能如下所示:
foo(foo const& other){
this->length = other.length;
this->ptr = new int[other.length];
copy(other.ptr, other.ptr + other.length, this->ptr);}如果这个构造函数是临时的,那么这个副本就没有必要了,因为我们知道这个临时构造函数只会被销毁,为什么不利用临时分配的资源呢?在C+03中,无法阻止复制,因为我们无法确定我们是临时传递的。在C+11中,我们可以重载一个移动构造函数:
foo(foo&& other){
this->length = other.length;
this->ptr = other.ptr;
other.length = 0;
other.ptr = nullptr;}注意这里最大的区别:Move构造函数实际上修改了它的参数。这将有效地“移动”临时对象到正在构造的对象中,从而消除不必要的副本。
属性显式转换为rvalue引用的临时和非Const值引用将使用移动构造函数。std::move函数(它只执行转换)。下面的代码都调用移动构造函数f1和f2:
foo f1((foo())); // Move a temporary into f1; temporary becomes "empty"foo f2 = std::move(f1); // Move f1 into f2; f1 is now "empty"
完美转发..rvalue引用允许我们正确地转发模板函数的参数。例如,这个工厂功能:
template <typename T, typename A1>std::unique_ptr<T> factory(A1& a1){
return std::unique_ptr<T>(new T(a1));}如果我们打电话factory<foo>(5),这个论点将被推断为int&,它不会绑定到文字5,即使foo构造函数采用int..好吧,我们可以用A1 const&,但如果foo接受非Const引用的构造函数参数?要建立一个真正通用的工厂功能,我们必须在A1&继续A1 const&..如果工厂采用一个参数类型,那么这可能很好,但是每一个附加的参数类型都会将所需的重载设置为2,这很快就无法维护了。
rvalue引用通过允许标准库定义std::forward函数,可以正确转发lvalue/rvalue引用。
这使我们能够像这样定义工厂函数:
template <typename T, typename A1>std::unique_ptr<T> factory(A1&& a1){
return std::unique_ptr<T>(new T(std::forward<A1>(a1)));}现在,参数的rvalue/lvalue-ness在传递给T的构造函数,这意味着如果使用rvalue调用工厂,T用rvalue调用工厂的构造函数。如果使用lvalue调用工厂,T它的构造函数是用lvalue调用的。改进后的工厂函数可以工作,因为有一个特殊的规则:
函数参数类型为
T&&哪里T是模板参数,函数参数是类型的lvalue。A,类型A&用于模板参数推导。
因此,我们可以像这样使用工厂:
auto p1 = factory<foo>(foo()); // calls foo(foo&&)auto p2 = factory<foo>(*p1); // calls foo(foo const&)
重要参考属性:
- 为了解决过载问题,
lvalue更喜欢绑定于lvalue引用,rvalue更喜欢绑定而不是rvalue引用。
..因此,临时人员为什么更喜欢调用移动构造函数/移动赋值操作符,而不是复制构造函数/赋值运算符。 rvalue引用将隐式绑定到rvalue和作为隐式转换结果的临时变量。
..E.
格式良好,因为Float是隐式可转换为int的;引用将是临时的,这是转换的结果。float f = 0f; int&& i = f;命名的rvalue引用是lvalue。未命名的rvalue引用是rvalue。
这一点很重要,请理解为什么
打电话是必要的,因为:std::movefoo&& r = foo(); foo f = std::move(r);
TA贡献1802条经验 获得超5个赞
指.的术语T&& 与类型扣除一起使用时(如用于完美转发)被通俗地称为转发参考..“普遍参考”一词是由ScottMeyers发明的
这是因为它可以是r值,也可以是l值。
例如:
// templatetemplate<class T> foo(T&& t) { ... }// autoauto&& t = ...;// typedeftypedef ... T;T&& t = ...;// decltypedecltype(...)&& t = ...;- 3 回答
- 0 关注
- 862 浏览
添加回答
举报
