Usefulness of std::make_pair and std::make_tuple in C++1z

℡╲_俬逩灬. 提交于 2019-12-18 11:20:13

问题


In my understanding, the sole reason for the existence of std::make_pair and std::make_tuple is that you don't have to write the types by yourself as they are automatically deduced. In C++1z, we have template argument deduction for class templates, which allows us to simply write

std::pair p(1, 2.5); // C++1z

instead of

auto p = std::make_pair(1, 2.5); // C++11/14

The situation for std::tuple is analogous. This leads to the following question: In C++1z, is there a situation in which it is beneficial to use std::make_pair and std::make_tuple instead of using the constructors of std::pair and std::tuple?

Please, consider just pure C++1z code (i.e. no need for backward compatibility with C++14) and assume that everyone is familiar with this C++1z feature.


回答1:


In C++1z, is there a situation in which it is beneficial to use std::make_pair and std::make_tuple instead of using the constructors of std::pair and std::tuple?

There are always fun exceptions to every rule. What do you want to happen to std::reference_wrapper?

int i = 42;
auto r = std::ref(i);

pair p(i, r);                 // std::pair<int, std::reference_wrapper<int> >
auto q = std::make_pair(i,r); // std::pair<int, int&>

If you want the latter, std::make_pair is what you want.


Another situation cames in generic code. Let's say I have a template parameter pack that I want to turn into a tuple, would I write this?

template <typename... Ts>
auto foo(Ts... ts) {
    return std::tuple(ts...);
}

Now the intent of that code is to probably to get a std::tuple<Ts...> out of it, but that's not necessarily what happens. It depends on Ts...:

  • if Ts... is a single object that is itself a tuple, you get a copy of it. That is, foo(std::tuple{1}) gives me a tuple<int> rather than a tuple<tuple<int>>.
  • if Ts... was a single object that is a pair, I get a tuple of those elements. That is, foo(std::pair{1, 2}) gives me a tuple<int, int> rather than a tuple<pair<int, int>>.

In generic code, I would stay away from using CTAD for types like tuple because it's never clear what you're going to get. make_tuple doesn't have this problem. make_tuple(tuple{1}) is a tuple<tuple<int>> and make_tuple(pair{1, 2}) is a tuple<pair<int, int>> because that's what you asked for.


Additionally, since std::make_pair is a function template, you can pass that into another function template that maybe wants to do something:

foo(std::make_pair<int, int>);

This doesn't seem super useful, but somebody somewhere is using it to solve a problem - and you can't just pass std::pair there.



来源:https://stackoverflow.com/questions/43875420/usefulness-of-stdmake-pair-and-stdmake-tuple-in-c1z

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!