2016-12-01 50 views
4

This code compiles但我不知道哪个版本应该是首选:的std ::领带VS的std :: make_tuple

#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; 
} 

,因为函数是由值返回一个元组不应该有任何使用问题std::tie对? (即没有悬挂参考)

回答

1

请注意std::tie。返回tie在逻辑上等同于返回一个引用,并附带所有的注意事项。

在逻辑上,这三个是等效的:

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

和此:

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

等效于此:

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

,因为它产生的其中之一:

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; 
} 
8

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,因为它是该任务的正确工具。

+0

也'的std :: make_tuple'更好地表达代码的意图。如果我看到调用'std :: tie'的代码,然后将它存储在一个'tuple'中,我可能会认为这是一个错误。 – SirGuy

1

tuple2应该更有效率。 tie确实会创建一个tuple,但是您必须记住的关于tie的事情是它不会创建类型为Args...的元组,但会生成一个类型为Args&...的元组,表示您的返回类型和元组不匹配。这意味着你需要从绑定的元组复制到返回元组。

在第二个示例中,您返回的元组与返回类型的类型相同,因此您可以直接返回该元组。你不必在那里复制。

相关问题