在C++1z中,是否存在使用std::make_pair
和std::make_tuple
而不是std::pair
和std::tuple
的构造函数更有利的情况?对于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&>
如果你想要后者,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...
是一个单独的对象,它本身就是一个pair
,那么你将得到这些元素的一个tuple
。也就是说,foo(std::pair{1, 2})
将给我一个tuple<int, int>
而不是一个tuple<pair<int, int>>
。
在通用代码中,我会避免使用像tuple
这样的类型的CTAD,因为你永远不知道你会得到什么。 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
。
std::make_pair
将std::reference_wrapper<T>
衰减为T&
。推导指南是否考虑到了这一点? - DeiDeimake_pair
之间存在差异。 - Kerrek SB