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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 12:50:04  来源:igfitidea点击:

What is std::pair?

c++booststlstd-pair

提问by Anthony

What is std::pairfor, why would I use it, and what benefits does boost::compressed_pairbring?

有什么std::pair用,我为什么要使用它,boost::compressed_pair带来什么好处?

采纳答案by jwfearn

std::pairis a data type for grouping two values together as a single object. std::mapuses it for key, value pairs.

std::pair是用于将两个值组合为单个对象的数据类型。 std::map将其用于键值对。

While you're learning pair, you might check out tuple. It's like pairbut for grouping an arbitrary number of values. tupleis 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,以获得详尽的解释。

alt text

替代文字

回答by Logan Capaldo

compressed_pairuses 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 Band Cto have the same size, even if sizeof(A)can't be zero.

在这里,它是罚款B,并C具有相同的尺寸,即使sizeof(A)不能为零。

So boost::compressed_pairtakes 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::pairmight 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 FirstTypeor SecondTypeis A, your pair<A, int>has to be bigger than sizeof(int).

这意味着,如果任一FirstType或者SecondTypeA,你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_pa​​ir 关心几个字节,这听起来很奇怪。但是,当考虑可以在何处使用compressed_pa​​ir 时,它实际上很重要。例如,让我们考虑以下代码:

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 _1as members in itself or in a std::pairin 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_pa​​ir 会突然产生很大的影响。如果 boost::bind 将函数指针和占位符_1作为成员存储在自身或 astd::pair中,会发生什么?好吧,它可能会膨胀到sizeof(&f) + sizeof(_1). 假设函数指针有 8 个字节(特别是对于成员函数并不少见)并且占位符有一个字节(请参阅 Logan 的答案以了解原因),那么我们可能需要 9 个字节用于绑定对象。由于对齐,这在通常的 32 位系统上最多可能膨胀 12 个字节。

boost::functionencourages its implementations to apply a small object optimization. That means that for smallfunctors, a small buffer directly embedded in the boost::functionobject 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_pa​​ir 能够优化掉大小为 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

It's standard class for storing a pair of values. It's returned/used by some standard functions, like std::map::insert.

它是用于存储一对值的标准类。它由一些标准函数返回/使用,例如std::map::insert.

boost::compressed_pairclaims to be more efficient: see here

boost::compressed_pair声称更有效:见这里

回答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_pa​​ir 很有用。当以编程方式从其他类型推断出该对的类型时,这通常用于模板元编程。最后,您通常会有某种形式的“空结构”。

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::pairis 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.

有时,您总是将两条信息一起传递,无论是作为参数,还是返回值,或其他。当然,您可以编写自己的对象,但如果它只是两个小的基元或类似的,有时一对似乎就可以了。