考虑这两种方法
方法1
std::tuple<TypeA, TypeB> res = function(args);
TypeA & a = std::get<0>(res);
TypeB & b = std::get<1>(res);
// use a and b as you want
方法2
TypeA a;
TypeB b;
std::tie(a, b) = function(args);
// use a and b as you want
我正在考虑这两种方法的优缺点。
方法2会导致额外费用吗?或者也许它们完全等效?
在c++17
中,结构绑定提供了一种更直观的解包元组的方法
auto [ var1, var2 ] = tuple;
与上面列出的另外两种方法相比,它将带来任何改善吗?还是只是语法糖?
答案 0 :(得分:2)
我要保证function
返回tuple<TypeA, TypeB>
。另外,由于我很懒,我将A
和B
用作TypeA
和TypeB
的别名。
auto&& [a,b] = function(args);
这是方法1的语法糖。
方法2首先在a
和b
上调用默认构造函数。然后,它使用tuple<A&,B&>=operator=(tuple<A,B>&&)
来分配a
和b
。然后将返回值tuple<A,B>
中创建的临时function
丢弃。
对于某些类型,这些操作没有可观察到的效果,因此不需要编译器执行任何工作。在其他类型中,创建临时对象然后对其进行赋值会产生观察效果。在这种情况下,编译器必须执行这些额外的操作。
优化auto&&[a,b]
对于编译器将更加容易,并且它还支持其他一些情况,例如
struct function_retval { int a, int b; };
function_retval function( int arg );
auto&&[a,b] = function(7);
另一个好处是它没有大量您不想在代码中谈论的命名变量。返回值的实际持有者将变为匿名。另外,decltype(a)
不是引用,与情况1不同,因为标准实际上是这样引用的,尽管它是引用。
({auto&&
只是意味着我不在乎是否将返回值存储在引用或值中;我使用任何function
返回的值)。