C++ 什么是 std::pair?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/97948/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is std::pair?
提问by Anthony
What is std::pair
for, why would I use it, and what benefits does boost::compressed_pair
bring?
有什么std::pair
用,我为什么要使用它,boost::compressed_pair
带来什么好处?
采纳答案by jwfearn
std::pair
is a data type for grouping two values together as a single object. std::map
uses it for key, value pairs.
std::pair
是用于将两个值组合为单个对象的数据类型。 std::map
将其用于键值对。
While you're learning pair
, you might check out tuple
. It's like pair
but for grouping an arbitrary number of values. tuple
is part of TR1 and many compilers already include it with their Standard Library implementations.
在学习的同时pair
,您可能会查看tuple
。这就像pair
但是对任意数量的值进行分组。 tuple
是 TR1 的一部分,许多编译器已经将它包含在他们的标准库实现中。
Also, checkout Chapter 1, "Tuples," of the book The C++ Standard Library Extensions: A Tutorial and Referenceby Pete Becker, ISBN-13: 9780321412997, for a thorough explanation.
此外,请查看Pete Becker 的The C++ Standard Library Extensions: A Tutorial and Reference一书的第 1 章“元组” ,ISBN-13:9780321412997,以获得详尽的解释。
回答by Logan Capaldo
compressed_pair
uses some template trickery to save space. In C++, an object (small o) can not have the same address as a different object.
compressed_pair
使用一些模板技巧来节省空间。在 C++ 中,对象(小 o)不能与不同的对象具有相同的地址。
So even if you have
所以即使你有
struct A { };
A
's size will not be 0, because then:
A
的大小不会是 0,因为这样:
A a1;
A a2;
&a1 == &a2;
would hold, which is not allowed.
将举行,这是不允许的。
Butmany compilers will do what is called the "empty base class optimization":
但是很多编译器会做所谓的“空基类优化”:
struct A { };
struct B { int x; };
struct C : public A { int x; };
Here, it is fine for B
and C
to have the same size, even if sizeof(A)
can't be zero.
在这里,它是罚款B
,并C
具有相同的尺寸,即使sizeof(A)
不能为零。
So boost::compressed_pair
takes advantage of this optimization and will, where possible, inherit from one or the other of the types in the pair if it is empty.
因此boost::compressed_pair
,利用这种优化,并在可能的情况下从该对中的一个或另一个类型继承,如果它为空。
So a std::pair
might look like (I've elided a good deal, ctors etc.):
所以std::pair
可能看起来像(我已经省略了很多,ctors 等):
template<typename FirstType, typename SecondType>
struct pair {
FirstType first;
SecondType second;
};
That means if either FirstType
or SecondType
is A
, your pair<A, int>
has to be bigger than sizeof(int)
.
这意味着,如果任一FirstType
或者SecondType
是A
,你pair<A, int>
必须比更大sizeof(int)
。
But if you use compressed_pair
, its generated code will look akin to:
但是,如果您使用compressed_pair
,其生成的代码将类似于:
struct compressed_pair<A,int> : private A {
int second_;
A first() { return *this; }
int second() { return second_; }
};
And compressed_pair<A,int>
will only be as big as sizeof(int).
并且compressed_pair<A,int>
只会和 sizeof(int) 一样大。
回答by Johannes Schaub - litb
It can sound strange to hear that compressed_pair cares about a couple of bytes. But it can actually be important when one considers where compressed_pair can be used. For example let's consider this code:
听到compressed_pair 关心几个字节,这听起来很奇怪。但是,当考虑可以在何处使用compressed_pair 时,它实际上很重要。例如,让我们考虑以下代码:
boost::function<void(int)> f(boost::bind(&f, _1));
It can suddenly have a big impact to use compressed_pair in cases like above. What could happen if boost::bind stores the function pointer and the place-holder _1
as members in itself or in a std::pair
in itself? Well, it could bloat up to sizeof(&f) + sizeof(_1)
. Assuming a function pointer has 8 bytes (not uncommon especially for member functions) and the placeholder has one byte (see Logan's answer for why), then we could have needed 9 bytes for the bind object. Because of aligning, this could bloat up to 12 bytes on a usual 32bit system.
在上述情况下,使用compressed_pair 会突然产生很大的影响。如果 boost::bind 将函数指针和占位符_1
作为成员存储在自身或 astd::pair
中,会发生什么?好吧,它可能会膨胀到sizeof(&f) + sizeof(_1)
. 假设函数指针有 8 个字节(特别是对于成员函数并不少见)并且占位符有一个字节(请参阅 Logan 的答案以了解原因),那么我们可能需要 9 个字节用于绑定对象。由于对齐,这在通常的 32 位系统上最多可能膨胀 12 个字节。
boost::function
encourages its implementations to apply a small object optimization. That means that for smallfunctors, a small buffer directly embedded in the boost::function
object is used to store the functor. For larger functors, the heap would have to be used by using operator new to get memory. Around boost version 1.34, it was decided to adopt this optimization, because it was figured one could gain some very great performance benefits.
boost::function
鼓励其实现应用小对象优化。这意味着对于小函子,直接嵌入boost::function
对象中的小缓冲区用于存储函子。对于较大的函子,必须通过使用 operator new 来使用堆来获取内存。在 boost 1.34 版左右,决定采用这种优化,因为它认为可以获得一些非常大的性能优势。
Now, a reasonable (yet, maybe still quite small) limit for such a small buffer would be 8 bytes. That is, our quite simple bind object would notfit into the small buffer, and would require operator new to be stored. If the bind object above would use a compressed_pair
, it can actually reduce its size to 8 bytes (or 4 bytes for non-member function pointer often), because the placeholder is nothing more than an empty object.
现在,对于这么小的缓冲区,合理(但可能仍然很小)的限制是 8 字节。也就是说,我们非常简单的绑定对象不适合小缓冲区,并且需要存储 operator new。如果上面的绑定对象使用 a compressed_pair
,它实际上可以将其大小减少到 8 个字节(对于非成员函数指针,通常为 4 个字节),因为占位符只不过是一个空对象。
So, what may look like just wasting a lot of thought for just only a few bytes actually can have a significant impact on performance.
因此,看起来只是为了几个字节而浪费大量思想实际上会对性能产生重大影响。
回答by David Pierre
You sometimes need to return 2 values from a function, and it's often overkill to go and create a class just for that.
有时您需要从函数中返回 2 个值,而为此创建一个类通常是过大的。
std:pair comes in handy in those cases.
std:pair 在这些情况下会派上用场。
I think boost:compressed_pair is able to optimize away the members of size 0. Which is mostly useful for heavy template machinery in libraries.
我认为 boost:compressed_pair 能够优化掉大小为 0 的成员。这对于库中的重型模板机制最有用。
If you do control the types directly, it's irrelevant.
如果您确实直接控制类型,则无关紧要。
回答by John Mulder
std::pair comes in handy for a couple of the other container classes in the STL.
std::pair 可用于 STL 中的其他几个容器类。
For example:
例如:
std::map<>
std::multimap<>
Both store std::pairs of keys and values.
两者都存储 std::pairs 键和值。
When using the map and multimap, you often access the elements using a pointer to a pair.
使用 map 和 multimap 时,您经常使用指向对的指针访问元素。
回答by user17481
回答by rlerallut
Additional info: boost::compressed_pair is useful when one of the pair's types is an empty struct. This is often used in template metaprogramming when the pair's types are programmatically inferred from other types. At then end, you usually have some form of "empty struct".
附加信息:当对的类型之一是空结构时,boost::compressed_pair 很有用。当以编程方式从其他类型推断出该对的类型时,这通常用于模板元编程。最后,您通常会有某种形式的“空结构”。
I would prefer std::pair for any "normal" use, unless you are into heavy template metaprogramming.
我更喜欢 std::pair 用于任何“正常”使用,除非您使用繁重的模板元编程。
回答by Andrei Taranchenko
It's nothing but a structure with two variables under the hood.
它只不过是一个带有两个变量的结构。
I actually dislike using std::pair for function returns. The reader of the code would have to know what .first is and what .second is.
我实际上不喜欢将 std::pair 用于函数返回。代码的读者必须知道 .first 是什么, .second 是什么。
The compromise I use sometimes is to immediately create constant references to .first and .second, while naming the references clearly.
我有时使用的妥协是立即创建对 .first 和 .second 的常量引用,同时清楚地命名引用。
回答by mloskot
What is std::pair for, why would I use it?
std::pair 有什么用,我为什么要使用它?
It is just as simple two elements tuple. It was defined in first version of STLin times when compilers were not widely supporting templates and metaprogramming techniques which would be required to implement more sophisticated type of tuple like Boost.Tuple.
它就像简单的两个元素元组。它是在STL 的第一个版本中定义的,当时编译器没有广泛支持模板和元编程技术,这些技术需要实现更复杂的元组类型,如Boost.Tuple。
It is useful in many situations. std::pair
is used in standard associative containers. It can be used as a simple form of range std::pair<iterator, iterator>
- so one may define algorithms accepting single object representing range instead of two iterators separately.
(It is a useful alternative in many situations.)
它在许多情况下都很有用。std::pair
用于标准关联容器。它可以用作范围的一种简单形式std::pair<iterator, iterator>
- 因此可以定义接受表示范围的单个对象而不是两个单独的迭代器的算法。(在许多情况下,这是一个有用的替代方案。)
回答by Aaron
Sometimes there are two pieces of information that you just always pass around together, whether as a parameter, or a return value, or whatever. Sure, you could write your own object, but if it's just two small primitives or similar, sometimes a pair seems just fine.
有时,您总是将两条信息一起传递,无论是作为参数,还是返回值,或其他。当然,您可以编写自己的对象,但如果它只是两个小的基元或类似的,有时一对似乎就可以了。