std :: tie vs std :: make_tuple

时间:2016-12-01 15:14:34

标签: c++ tuples

This code compiles但我想知道应该首选哪个版本:

#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时不应该有任何问题吗? (即没有悬空参考)

3 个答案:

答案 0 :(得分:10)

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

答案 1 :(得分:9)

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> 自{/ 1}}构建

现在,编译器可能会优化这种结构,但我不打算这样做。使用std::tuple<int&,int&,int&>,因为它是该任务的正确工具。

答案 2 :(得分:1)

def CreateEvent(auth, calendar, subject, start_time, end_time, attendees, content): create_url = 'https://outlook.office365.com/api/v1.0/me/calendars/{0}/events'.format(calendar) headers = {'Content-type': 'application/json', 'Accept': 'application/json'} data = {} data['Subject'] = subject data['Start'] = start_time data['End'] = end_time data['Attendees'] = attendees data['Body']['Content'] = content data['Body']['ContentType'] = 'Text' content_data = json.dumps(data) 应该更有效率。 tuple2确实会创建一个tie,但您必须记住的关于tuple的事情是,它不会生成tie类型的元组,而是生成类型为{{{1}的元组。 1}}表示你的返回类型和你的元组不匹配。这意味着你需要从绑定的元组复制到返回元组。

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