C++ 使用std::tie打开包装返回值是否会导致额外成本?
考虑这两种方法 方法1C++ 使用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,
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,我会坚持使用结构化绑定,因为它们看起来更好