是否有任何理由将返回值捕获为rvalue参考
Is there any reason to capture a return-value as an rvalue-reference?
我有一个仅动作的struct Foo
,函数 Foo get();
如果我想以可变的方式捕获get
的返回值,我有两个选择:
- 按值(
Foo
) - rvalue-Reference(
Foo&&
)
当我通过rvalue-reference捕获时,我会创建一个lvalue,就像按值捕获。
我正在努力看到不同选项之间的观点?
- 这两个之间是否有之间的区别?
工作示例:
#include <iostream>
struct Foo
{
Foo(std::string s) : s(std::move(s)) {}
Foo(Foo&& f) : s(std::move(f.s)) {}
Foo(const Foo&) = delete;
Foo& operator=(const Foo&) = delete;
std::string s;
};
Foo get()
{
return Foo { "hello" };
}
int main()
{
// capture return value as l-value
Foo lv1 = get();
// move into another lvalue
Foo lv2 = std::move(lv1);
std::cout << lv2.s << 'n';
// capture return value as r-value reference
Foo&& rv1 = get();
// move into another lvalue
Foo lv3 = std::move(rv1);
std::cout << lv3.s << 'n';
return 0;
}
Foo lv1 = get();
这要求Foo
是复制/可移动。
Foo&& rv1 = get();
这不是(至少不到这一代码行; get
的实现仍然需要一个)。
即使允许编译器将返回值的副本列入变量,但该表格的副本初始化仍然需要可访问的副本或移动构造函数。
因此,如果您想对Foo
的类型施加尽可能少的限制,则可以存储返回值的&&
。
当然,C 17更改此规则,因此第一个规则不需要复制/移动构造函数。
Foo&&
这将创建对临时值的引用(或存储分配给其的RVALUE参考)。如果它存储了对临时值的引用,则其寿命会扩展值。
Foo
这将存储一个值的副本,无论返回什么。
在C 11和14中,如果无法移动Foo
,则将Foo make_foo()
分配给Foo
类型的变量是非法的。即使省略了移动,也有一个移动(返回值和外部范围中的值已合并了寿命)。
在C 17中,保证省略意味着不存在移动构造器。
Foo x = make_foo(); // Foo make_foo()
C 17中的上述内容保证make_foo()
的返回值仅名为x
。实际上, make_foo
中的临时也可能是 x
;具有不同名称的相同对象。不需要移动。
还有其他一些细微的差异。decltype(x)
将返回x
的声明类型;因此,Foo
或Foo&&
取决于
另一个重要区别是它与auto
一起使用。
auto&& x = some_function();
这将创建对任何事物的引用。如果some_function
返回临时性,它将绑定对其的RVALUE引用并延长其寿命。如果返回参考,x
匹配参考的类型。
auto x = some_function();
这会创建一个值,该值可以从some_function
返回的内容复制,或者如果some_function
的返回值返回临时值。
auto&&
在某种意义上是指"只要使它起作用,不要做额外的工作",它可以推断为Foo&&
。auto
的意思是"存储副本"。
在"几乎总是自动"样式中,这些将比显式Foo
或Foo&&
更常见。
auto&&
永远不会推断为Foo
,但可以推断为Foo&&
。
auto&&
的最常见用途,即使在几乎总是自动之外,也是:
for(auto&& x : range)
x
成为迭代范围内迭代的一种有效方法,我们不在乎哪种类型的range
有很多。另一个常见用途是:
[](auto&& x){ /* some code */ }
lambdas通常用于类型很明显且不值得再次键入的上下文中,例如传递到算法之类的上下文。通过使用auto&&
用于参数类型,我们使代码少详细。
- RVALUE参考与const lVALUE参考作为参数之间的混淆
- 如何使对象通过RVALUE参考通过而没有复制
- RVALUE参考与LVALUE结合
- RVALUE参考和多态性
- 是转发参考是否仍然是RVALUE参考
- 在平等符号左侧使用RVALUE参考的规则是什么?
- 为什么const rvalue合格的std ::可选:: value()返回const rvalue参考
- C 11:为什么RVALUE参考参数隐式转换为LVALUE
- 模板功能不使用RVALUE参考实例化/接收呼叫
- 作为RVALUE参考与双移动值的传递
- rvalue参考vector :: push_back函数如何提高效率
- 函数返回rvalue参考是否有意义
- 用rvalue参考和变异模板bits bits bys blamda by
- 移动后通过rvalue参考返回
- 为什么STD :: MOVE将RVALUE参考作为参数
- 成员函数返回成员变量的RVALUE参考
- 反复调用MOVE,其中需要RVALUE参考
- 产生副本作为输入,以获取RVALUE参考
- C 接收const lvalue和rvalue参考参数,而无需过载
- rvalue参考绑定到std ::功能类型的LVALUE