本文介绍了C ++ 1z中std :: make_pair和std :: make_tuple的用处的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我了解,存在和的好处是您不必自己编写类型,因为它们是自动推导的。在C ++ 1z中,我们有,它使我们可以简单地编写

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

而不是

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

是类似的。这导致以下问题:在C ++ 1z中,是否存在使用 std :: make_pair 和 std的情况是有利的: :make_tuple 而不是使用 std :: pair 和 std :: tuple 的构造函数?



请考虑仅使用纯C ++ 1z代码(即无需与C ++ 14向后兼容),并假定每个人都熟悉此C ++。 1z功能。

解决方案

每条规则总是有有趣的例外。您想对 std :: reference_wrapper 做什么?

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

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

如果需要后者,请 std :: make_pair 是您想要的。






在通用代码中出现了另一种情况。假设我有一个要转换为元组的模板参数包,我会写这个吗?

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

现在,该代码的目的可能是获得 std :: tuple< Ts ...> ,但这不是不必要会发生的事情。这取决于 Ts ... :




  • 如果 Ts ... 是一个单独的对象,它本身就是一个 tuple ,您可以得到它的副本。也就是说, foo(std :: tuple {1})给了我 tuple< int> 而不是 tuple< tuple< int>> 。

  • 如果 Ts ... 是一个对对的单个对象,我得到了那些元素的元组。也就是说, foo(std :: pair {1,2})给了我 tuple< int,int> 而不是 tuple< pair< int,int>> 。



在通用代码中,我会避​​免将CTAD用于 tuple 之类的类型,因为目前尚不清楚要获得什么。 make_tuple 没有这个问题。 make_tuple(tuple {1})是 tuple< tuple< int>> 和 make_tuple(pair {1,2})是 tuple< pair< int,int>> ,因为这就是您要的。




另外,由于 std :: make_pair 是函数模板,您可以将其传递给可能想要执行某些操作的另一个函数模板:

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

这似乎没什么用,但是有人在用它来解决问题-而您不能只在其中传递 std :: pair 。


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.

解决方案

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.

这篇关于C ++ 1z中std :: make_pair和std :: make_tuple的用处的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 10:15