std::make_pair 与 std::pair 构造函数的目的是什么?
std::make_pair
的用途是什么?
为什么不直接执行 std::pair
这两种方法有什么区别吗?
What is the purpose of std::make_pair
?
Why not just do std::pair<int, char>(0, 'a')
?
Is there any difference between the two methods?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
(由于 CTAD,此答案仅适用于 C++14 及更早的标准)< /strong>
区别在于,使用
std::pair
您需要指定两个元素的类型,而std::make_pair
将创建一个对传递给它的元素的类型,而不需要告诉它。无论如何,这就是我可以从各种文档中收集到的内容。请参阅 http://www.cplusplus.com/reference/std/utility/ 中的示例make_pair/
必须执行此操作,随着时间的推移,这会很烦人......
除了它的隐式转换奖励之外,如果您不使用 make_pair,则每次分配给一个时都
(This answer is only correct for C++14 and earlier standards, due to CTAD)
The difference is that with
std::pair
you need to specify the types of both elements, whereasstd::make_pair
will create a pair with the type of the elements that are passed to it, without you needing to tell it. That's what I could gather from various docs anyways.See this example from http://www.cplusplus.com/reference/std/utility/make_pair/
Aside from the implicit conversion bonus of it, if you didn't use make_pair you'd have to do
every time you assigned to one, which would be annoying over time...
在 C++17 之前,无法从构造函数推断出类模板参数
在 C++17 之前,您不能编写如下内容:
因为这会从构造函数参数推断模板类型,所以您必须编写它明确为:
C++17 使该语法成为可能,因此
make_pair
是多余的。在 C++17 之前,
std::make_pair
允许我们编写更少冗长的代码:而不是更冗长的代码:
它会重复类型,并且可能会很长。
类型推断适用于 C++17 之前的情况,因为
make_pair
不是构造函数。make_pair
本质上等同于:相同的概念适用于
inserter
与insert_iterator
。另请参阅:
最小示例
为了使事情更具体,我们可以用以下代码最小化地观察问题: :
main.cpp
then:
愉快地编译,但是:
失败了:
并且需要改为工作:
或 helper:
它使用常规函数而不是构造函数。
std::reference_wrapper 的差异
这个comment 提到
std::make_pair
解包std::reference_wrapper
而构造函数则不然,所以这是一个区别。待办事项示例。使用 GCC 8.1.0、Ubuntu 16.04。
Class template arguments could not be inferred from the constructor before C++17
Before C++17 you could not write something like:
since that would infer template types from the constructor arguments, you had to write it explicitly as:
C++17 makes that syntax possible, and therefore
make_pair
redundant.Before C++17,
std::make_pair
allowed us to write less verbose code:instead of the more verbose:
which repeats the types, and can be very long.
Type inference works in that pre-C++17 case because
make_pair
is not a constructor.make_pair
is essentially equivalent to:The same concept applies to
inserter
vsinsert_iterator
.See also:
Minimal example
To make things more concrete, we can observe the problem minimally with:
main.cpp
then:
compiles happily, but:
fails with:
and requires instead to work:
or the helper:
which uses a regular function instead of a constructor.
Difference for
std::reference_wrapper
This comment mentions that
std::make_pair
unwrapsstd::reference_wrapper
while the constructor does not, so that's one difference. TODO example.Tested with GCC 8.1.0, Ubuntu 16.04.
正如 @MSalters 上面回复的那样,您现在可以使用大括号在 C++11 中执行此操作(刚刚使用 C++11 编译器验证了这一点):
As @MSalters replied above, you can now use curly braces to do this in C++11 (just verified this with a C++11 compiler):
使用
make_pair
和使用指定类型参数显式调用pair
构造函数没有区别。当类型很详细时,std::make_pair 会更方便,因为模板方法会根据给定的参数进行类型推导。例如,
There is no difference between using
make_pair
and explicitly calling thepair
constructor with specified type arguments.std::make_pair
is more convenient when the types are verbose because a template method has type deduction based on its given parameters.For example,
值得注意的是,这是 C++ 模板编程中的常见习惯用法。它被称为对象生成器习惯用法,您可以在此处找到更多信息和一个很好的示例。
编辑正如有人在评论中建议的那样(已删除),以下是对链接的稍微修改的摘录,以防链接中断。
对象生成器允许创建对象而无需显式指定其类型。它基于类模板所没有的函数模板的一个有用属性:函数模板的类型参数是从其实际参数自动推导出来的。
std::make_pair
是一个简单的示例,它根据std::make_pair
的实际参数返回std::pair
模板的实例> 功能。It's worth noting that this is a common idiom in C++ template programming. It's known as the Object Generator idiom, you can find more information and a nice example here.
Edit As someone suggested in the comments (since removed) the following is a slightly modified extract from the link in case it breaks.
An Object Generator allows creation of objects without explicitly specifying their types. It is based on a useful property of function templates which class templates don't have: The type parameters of a function template are deduced automatically from its actual parameters.
std::make_pair
is a simple example that returns an instance of thestd::pair
template depending on the actual parameters of thestd::make_pair
function.make_pair 在直接构造函数上创建一个额外的副本。我总是用 typedef 来提供简单的语法。
这显示了差异(Rampal Chaudhary 的示例):
make_pair creates an extra copy over the direct constructor. I always typedef my pairs to provide simple syntax.
This shows the difference (example by Rampal Chaudhary):
从 c++11 开始,只对对使用统一初始化。所以而不是:
或
只是使用
starting from c++11 just use uniform initialization for pairs. So instead of:
or
just use
我永远不会再使用 std::make_pair ,因为它已经“损坏”了(从我的角度来看 - 至少它不直观)。考虑以下示例
您有一个后备存储,或者一个字符串池
如果您尝试像这样插入到 std::map 中;
这将会失败,而且非常失败。它将首先创建
std::string
的副本,然后将其转换为std::string_view
> - 现在, string_view 指向“任何地方”。它可能有效,也可能无效。我最近刚刚测试过这个。但是,如果您改为使用,
编译器上帝将正确地将其推断为 string_pool 内容上的
string_view
并且可以工作 - 没有std::string
的中间副本,变成string_view
我从中得到的教训或收获是 - 永远、永远、永远、永远使用 std::make_pair。
I'm never going to use
std::make_pair
again because it's "broken" (from my perspective - at least it's unintuitive). Consider the following exampleYou have a backing storage, or a string pool of
If you attempt to insert into
std::map
like so;This will fail, spectacularly. It will first create a copy of the
std::string
which then will be turned into astd::string_view
- and now, that string_view is pointing to "anywhere". It might work, it might not work. I tested this just recently.However, if you instead use
This will correctly be deduced by the Compiler Gods as a
string_view
over the string_pool contents and will work - no intermediary copy of astd::string
, turned into astring_view
My lesson or takeaway I gather from this is - never, ever, ever, ever use std::make_pair.