Std :: tie vs std :: make_tuple

This code compiles , but I wonder which version should be preferred:

#include <iostream>
#include <tuple>
using namespace std;

tuple<int, int, int> return_tuple1() {
    int a = 33;
    int b = 22;
    int c = 31;
    return tie(a, b, c);
}

tuple<int, int, int> return_tuple2() {
    int a = 33;
    int b = 22;
    int c = 31;
    return make_tuple(a, b, c);
}

int main() {
    auto a = return_tuple1();
    auto b = return_tuple2();
    return 0;
}

since the function returns a tuple by value, shouldn't there be any problems when using std::tieright? (i.e. no dangling links)

+4
source share
3 answers

Be very careful with std::tie. Returning a is tielogically equivalent to returning a link with all the caveats that come with it.

Logically, these three are equivalent:

int& foo();
std::reference_wrapper<int> foo();
std::tuple<int&> foo();

and this:

int a = 10;
return std::tie(a);

equivalent to this:

int a = 10;
return std::ref(a);

because it returns one of the following values:

std::tuple<int&>

. auto :

#include <iostream>
#include <tuple>
using namespace std;

auto return_tuple1() {  // function name is now lying
    int a = 33;         // it should be return_chaos()
    int b = 22;
    int c = 31;
    return tie(a, b, c);
}

auto return_tuple2() {
    int a = 33;
    int b = 22;
    int c = 31;
    return make_tuple(a, b, c);
}

int main() {
    auto a = return_tuple1(); // uh-oh...

    auto b = return_tuple2();

    std::get<0>(a); // undefined behaviour - if you're lucky you'll get a segfault at some point.
    std::get<0>(b); // perfectly ok
    return 0;
}
+1

std::tie , .
std::tie tuple , return_tuple1() , :

tuple<int, int, int> return_tuple1() {
    int a = 33;
    int b = 22;
    int c = 31;
    return std::tuple<int&,int&,int&>(a,b,c);
}

tuple<int, int, int> std::tuple<int&,int&,int&>.

, , . std::make_tuple, .

+8

tuple2should be more effective. tiecreates tuple, but the thing you should remember about tieis that it does not make a type tuple Args..., but instead does a type tuple Args&..., which means your return type and your tuple are not the same. This means that you need to copy from the bound tuple to the correct tuple.

In the second example, you return a tuple with the same type as the return type so that you can directly return it. You do not need to copy it.

+1
source

Source: https://habr.com/ru/post/1662548/


All Articles