什么是 std::pair?
std::pair
是什么,为什么要使用它,以及 boost::compressed_pair
带来什么好处?
What is std::pair
for, why would I use it, and what benefits does boost::compressed_pair
bring?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
compressed_pair
使用一些模板技巧来节省空间。 在 C++ 中,一个对象(小 o)不能与另一个对象具有相同的地址。所以即使你有
A
的大小也不会是 0,因为 then:会成立,这是不允许的。
但是许多编译器会执行所谓的“空基类优化”:
在这里,
B
和C
具有相同的值就可以了大小,即使sizeof(A)
不能为零。因此,
boost::compressed_pair
利用了这种优化,并且在可能的情况下,从该对中的一个或另一个类型(如果该类型为空)继承。所以
std::pair
可能看起来像(我已经省略了很多,ctors 等):这意味着如果
FirstType
或SecondType
是A
,您的pair
必须大于sizeof(int)
。但如果您使用
compressed_pair
,其生成的代码将类似于:并且
compressed_pair
将仅与 sizeof(int) 一样大。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.So even if you have
A
's size will not be 0, because then:would hold, which is not allowed.
But many compilers will do what is called the "empty base class optimization":
Here, it is fine for
B
andC
to have the same size, even ifsizeof(A)
can't be zero.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.So a
std::pair
might look like (I've elided a good deal, ctors etc.):That means if either
FirstType
orSecondType
isA
, yourpair<A, int>
has to be bigger thansizeof(int)
.But if you use
compressed_pair
, its generated code will look akin to:And
compressed_pair<A,int>
will only be as big as sizeof(int).std::pair
是一种数据类型将两个值组合在一起作为一个对象。std::map
使用它作为键,值对。当您学习
pair
时,您可能查看元组
。 它类似于pair
,但用于对任意数量的值进行分组。tuple
是 TR1 的一部分,许多编译器已将其包含在其标准库实现中。另外,请查看 Pete Becker 所著的《C++ 标准库扩展:教程和参考》一书的第 1 章“元组”,ISBN-13:9780321412997,以获得全面的解释。
std::pair
is a data type for grouping two values together as a single object.std::map
uses it for key, value pairs.While you're learning
pair
, you might check outtuple
. It's likepair
but for grouping an arbitrary number of values.tuple
is part of TR1 and many compilers already include it with their Standard Library implementations.Also, checkout Chapter 1, "Tuples," of the book The C++ Standard Library Extensions: A Tutorial and Reference by Pete Becker, ISBN-13: 9780321412997, for a thorough explanation.
有时您需要从函数返回 2 个值,而为此创建一个类通常是多余的。
std:pair 在这些情况下会派上用场。
我认为 boost:compressed_pair 能够优化掉大小为 0 的成员。
这对于图书馆中的重型模板机械最有用。
如果您直接控制类型,那就无关紧要了。
You sometimes need to return 2 values from a function, and it's often overkill to go and create a class just for that.
std:pair comes in handy in those cases.
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.
If you do control the types directly, it's irrelevant.
听到压缩对关心几个字节听起来很奇怪。 但当人们考虑在哪里可以使用compressed_pair时,它实际上很重要。 例如,让我们考虑一下这段代码:
在上面的情况下使用compressed_pair可能会突然产生很大的影响。 如果 boost::bind 将函数指针和占位符
_1
存储为本身的成员或本身的std::pair
中,会发生什么? 好吧,它可能会膨胀到sizeof(&f) + sizeof(_1)
。 假设函数指针有 8 个字节(对于成员函数来说并不罕见)并且占位符有 1 个字节(请参阅 Logan 的回答了解原因),那么我们可能需要 9 个字节用于绑定对象。 由于对齐,这在通常的 32 位系统上可能会膨胀多达 12 个字节。boost::function
鼓励其实现应用小对象优化。 这意味着对于小型仿函数,直接嵌入到boost::function
对象中的一个小缓冲区用于存储仿函数。 对于较大的函子,必须通过使用运算符 new 来使用堆来获取内存。 在 boost 版本 1.34 左右,决定采用 此优化,因为人们认为可以获得一些非常好的性能优势。现在,对于如此小的缓冲区来说,合理的(但可能仍然很小)限制是 8 个字节。 也就是说,我们非常简单的绑定对象无法放入小缓冲区中,并且需要存储operator new。 如果上面的绑定对象使用
compressed_pair
,它实际上可以将其大小减少到 8 个字节(对于非成员函数指针通常为 4 个字节),因为占位符只不过是一个空对象。因此,看似仅仅为了几个字节而浪费大量思考实际上可能会对性能产生重大影响。
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:
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 astd::pair
in itself? Well, it could bloat up tosizeof(&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.boost::function
encourages its implementations to apply a small object optimization. That means that for small functors, a small buffer directly embedded in theboost::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.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 not fit 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.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.
它是用于存储一对值的标准类。 它由一些标准函数返回/使用,例如 std::map::insert 。
boost::compressed_pair
声称更高效:看这里It's standard class for storing a pair of values. It's returned/used by some standard functions, like
std::map::insert
.boost::compressed_pair
claims to be more efficient: see here它就像简单的两个元素元组一样。 它是在 STL 的第一个版本中定义的,当时编译器尚未广泛支持实现更复杂类型的元组所需的模板和元编程技术,例如 Boost.Tuple。
它在很多情况下都很有用。
std::pair
用于标准关联容器。 它可以用作 rangestd::pair
的简单形式 - 因此可以定义接受表示范围的单个对象而不是分别接受两个迭代器的算法。(在许多情况下这是一个有用的替代方案。)
It is just as simple two elements tuple. It was defined in first version of STL in 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.
It is useful in many situations.
std::pair
is used in standard associative containers. It can be used as a simple form of rangestd::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.)
有时,您总是一起传递两条信息,无论是作为参数,还是作为返回值,或者其他什么。 当然,您可以编写自己的对象,但如果它只是两个小的基元或类似的对象,有时一对似乎就可以了。
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.
附加信息:当该对的类型之一是空结构时,boost::compressed_pair 很有用。 当以编程方式从其他类型推断出对的类型时,这通常在模板元编程中使用。 最后,您通常会得到某种形式的“空结构”。
我更喜欢 std::pair 进行任何“正常”使用,除非您喜欢繁重的模板元编程。
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".
I would prefer std::pair for any "normal" use, unless you are into heavy template metaprogramming.
它只不过是一个在幕后有两个变量的结构。
我实际上不喜欢使用 std::pair 来返回函数。 代码的读者必须知道什么是 .first 和什么是 .second。
我有时使用的折衷方案是立即创建对 .first 和 .second 的常量引用,同时明确命名引用。
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.
The compromise I use sometimes is to immediately create constant references to .first and .second, while naming the references clearly.
std::pair 对于 STL 中的其他几个容器类非常有用。
例如:
两者都存储 std:: 键和值对。
使用映射和多重映射时,您经常使用指向对的指针来访问元素。
std::pair comes in handy for a couple of the other container classes in the STL.
For example:
Both store std::pairs of keys and values.
When using the map and multimap, you often access the elements using a pointer to a pair.