C++ 使用std::tie打开包装返回值是否会导致额外成本?

C++ 使用std::tie打开包装返回值是否会导致额外成本?,c++,c++11,c++17,C++,C++11,C++17,考虑这两种方法 方法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会导致额外成本吗?或者它们完全相同 在c++17中,结构绑定提供了一种更直观的解包元组的方法 auto [ var1,

考虑这两种方法

方法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会导致额外成本吗?或者它们完全相同

c++17
中,结构绑定提供了一种更直观的解包元组的方法

auto [ var1, var2 ] = tuple;

与上面列出的另外两种方法相比,它会带来任何改进吗?或者它只是语法上的糖分?

我在假设
函数
返回
元组
。此外,我使用
A
B
作为
TypeA
TypeB
的别名,因为我很懒

auto&& [a,b] = function(args);
这是方法1的语法糖

方法2首先调用
a
b
上的默认构造函数。然后它使用
tuple=operator=(tuple&&)
分配
a
b
。然后,在
函数
的返回值中创建的临时
元组
将被丢弃

对于某些类型,这些操作没有可观察的效果,因此编译器不需要做任何工作。在其他类型中,通过创建临时对象然后在其上指定,会产生观察效果;在这种情况下,编译器必须执行这些额外的操作

优化
auto&[a,b]
对编译器来说会更容易,而且它还支持一些其他情况,如

struct function_retval { int a, int b; };
function_retval function( int arg );

auto&&[a,b] = function(7);
另外一个好处是,它没有一堆您不想在代码中谈论的命名变量。返回值的实际持有者变成匿名者。另外,
decltype(a)
与案例1不同,它不是一个参考,因为标准中这样说,即使它实际上是一个参考


auto&&
仅仅意味着我不在乎返回值是存储在引用中还是存储在值中;我使用
函数
返回的任何内容)。

我假设
函数
返回
元组
。此外,我使用
A
B
作为
TypeA
TypeB
的别名,因为我很懒

auto&& [a,b] = function(args);
这是方法1的语法糖

方法2首先调用
a
b
上的默认构造函数。然后它使用
tuple=operator=(tuple&&)
分配
a
b
。然后,在
函数
的返回值中创建的临时
元组
将被丢弃

对于某些类型,这些操作没有可观察的效果,因此编译器不需要做任何工作。在其他类型中,通过创建临时对象然后在其上指定,会产生观察效果;在这种情况下,编译器必须执行这些额外的操作

优化
auto&[a,b]
对编译器来说会更容易,而且它还支持一些其他情况,如

struct function_retval { int a, int b; };
function_retval function( int arg );

auto&&[a,b] = function(7);
另外一个好处是,它没有一堆您不想在代码中谈论的命名变量。返回值的实际持有者变成匿名者。另外,
decltype(a)
与案例1不同,它不是一个参考,因为标准中这样说,即使它实际上是一个参考


auto&&
简单地说,我不在乎返回值是存储在引用中还是存储在值中;我使用
函数返回的任何内容)。

您始终可以编译和检查程序集。我怀疑一个好的优化器会使1和2变得相同。如果你能使用C++17,我会坚持使用结构化绑定,因为它们看起来不错。你可以随时编译和检查程序集。我怀疑一个好的优化器会使1和2变得相同。如果你能使用C++17,我会坚持使用结构化绑定,因为它们看起来更好