什么是std :: pair?

Ant*_*ony 42 c++ boost stl std-pair

什么是std::pair,为什么我会使用它,以及boost::compressed_pair带来什么好处?

Log*_*ldo 81

compressed_pair使用一些模板技巧来节省空间.在C++中,对象(小o)不能具有与不同对象相同的地址.

所以,即使你有

struct A { };
Run Code Online (Sandbox Code Playgroud)

A的大小不会是0,因为那样:

A a1;
A a2;
&a1 == &a2;
Run Code Online (Sandbox Code Playgroud)

会坚持,这是不允许的.

但是许多编译器会做所谓的"空基类优化":

struct A { };
struct B { int x; };
struct C : public A { int x; };
Run Code Online (Sandbox Code Playgroud)

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

因此boost::compressed_pair,利用此优化,并且如果可能的话,如果它是空的,则将继承该对中的一个或另一个类型.

所以std::pair可能看起来像(我已经省略了很多,ctors等):

template<typename FirstType, typename SecondType>
struct pair {
   FirstType first;
   SecondType second;
};
Run Code Online (Sandbox Code Playgroud)

这意味着,如果任一FirstType或者SecondTypeA,你pair<A, int>必须比更大sizeof(int).

但是如果你使用compressed_pair,它生成的代码将类似于:

 struct compressed_pair<A,int> : private A {
    int second_;
    A first() { return *this; }
    int second() { return second_; }
 };
Run Code Online (Sandbox Code Playgroud)

并且compressed_pair<A,int>只会与sizeof(int)一样大.

  • 另外,我想补充说,除非你正在进行一些繁重的泛型编程,否则compress_pair是完全无用的,因为没有(我的意思是)现实生活中你把一个没有数据的类放在一对中. (6认同)

jwf*_*arn 35

std::pair是一种数据类型,用于将两个值组合在一起作为单个对象. std::map将它用于键值对.

在你学习的同时pair,你可能会看看tuple.它就像pair分组任意数量的值一样. tuple是TR1的一部分,许多编译器已将其与标准库实现包含在内.

另外,请查阅" C++标准库扩展: Pete Becker的教程和参考 "一书中第1章"元组" ,ISBN-13:9780321412997,以获得详尽的解释.

替代文字


Dav*_*rre 11

有时你需要从一个函数中返回2个值,并且为此创建一个类通常是过度的.

std:pair在这些情况下派上用场.

我认为boost:compressed_pa​​ir能够优化大小为0的成员.这对于库中的重模板机制来说非常有用.

如果你直接控制类型,那就无关紧要了.

  • 你可以使用boost :: tie来编写近似"a,b = func();"的代码.您可以编写:"boost :: tie(a,b)= func();"而不是显式实例化一对. (3认同)

Joh*_*itb 11

听到compressed_pa​​ir关心几个字节听起来很奇怪.但是当考虑可以使用compressed_pa​​ir的位置时,它实际上很重要.例如,让我们考虑一下这段代码:

boost::function<void(int)> f(boost::bind(&f, _1));
Run Code Online (Sandbox Code Playgroud)

在上述情况下使用compressed_pa​​ir会突然产生很大的影响.如果boost :: bind将函数指针和占位符存储_1为成员本身或std::pair本身存在,会发生什么?好吧,它可能会膨胀sizeof(&f) + sizeof(_1).假设函数指针有8个字节(对于成员函数来说并不罕见)并且占位符有一个字节(请参阅Logan的答案原因),那么我们可能需要9个字节用于绑定对象.由于对齐,在通常的32位系统上,这可能会膨胀到12个字节.

boost::function鼓励其实现应用小对象优化.这意味着对于小型仿函数,直接嵌入boost::function对象中的小缓冲区用于存储仿函数.对于较大的仿函数,必须使用operator new来获取内存.在升级版本1.34之后,决定采用这种优化,因为它被认为可以获得一些非常好的性能优势.

现在,这种小缓冲区的合理(但可能仍然非常小)限制将是8个字节.也就是说,我们非常简单的绑定对象适合小缓冲区,并且需要存储new运算符.如果上面的绑定对象使用a compressed_pair,它实际上可以将其大小减小到8个字节(或者经常是非成员函数指针的4个字节),因为占位符只不过是一个空对象.

因此,看起来只是浪费了很多想法,实际上只会对性能产生重大影响.