什么是std :: pair?
什么是std::pair
,为什么我会使用它, boost::compressed_pair
带来了什么好处?
std::pair
是用于将两个值组合为一个对象的数据types。 std::map
将它用于键值对。
在你学习pair
,你可能会签出tuple
。 这就像pair
但分组任意数量的值。 tuple
是TR1的一部分,许多编译器已经将它包含在标准库实现中。
此外,请仔细阅读“C ++标准库扩展: Pete Becker 教程和参考” (ISBN-13:9780321412997)中的第1章“元组”。
替代文字http://ak.buy.com/db_assets/prod_images/225/202452225.jpg
compressed_pair
使用一些模板欺骗来节省空间。 在C ++中,对象(小o)不能具有与另一个对象相同的地址。
所以即使你有
struct A { };
A
的大小不会是0,因为那么:
A a1; A a2; &a1 == &a2;
将持有,这是不允许的。
但是许多编译器会做所谓的“空基类优化”:
struct A { }; struct B { int x; }; struct C : public A { int x; };
在这里, B
和C
是相同的大小,即使sizeof(A)
不能为零。
所以boost::compressed_pair
利用了这个优化,如果可能的话,将会从这个类中的一个类inheritance,如果它是空的。
所以一个std::pair
可能看起来像(我已经消除了很多,ctors等):
template<typename FirstType, typename SecondType> struct pair { FirstType first; SecondType second; };
这意味着如果FirstType
或SecondType
是A
,那么pair<A, int>
对必须大于sizeof(int)
。
但是,如果使用compressed_pair
,则其生成的代码将类似于:
struct compressed_pair<A,int> : private A { int second_; A first() { return *this; } int second() { return second_; } };
而compressed_pair<A,int>
只会和sizeof(int)一样大。
你有时需要从函数中返回2个值,为了这个目的创build一个类往往是矫枉过正的。
std:对在这些情况下派上用场。
我认为boost:compressed_pair能够优化大小为0的成员。这对于库中大量的模板机制是非常有用的。
如果你直接控制types,这是不相关的。
听到compressed_pair关心几个字节听起来很奇怪。 但是,当考虑可以使用compressed_pair时,它实际上可能很重要。 例如让我们考虑这个代码:
boost::function<void(int)> f(boost::bind(&f, _1));
在上面的情况下,使用compressed_pair会突然产生很大的影响。 如果boost :: bind将函数指针和占位符_1
作为成员自身或std::pair
本身存储,会发生什么情况? 那么,它可能膨胀到sizeof(&f) + sizeof(_1)
。 假设一个函数指针有8个字节(对于成员函数来说并不less见),占位符有一个字节(请参阅Logan的答案),那么我们可能需要9个字节的绑定对象。 由于alignment,通常的32位系统可能会膨胀到12个字节。
boost::function
鼓励它的实现应用一个小对象优化。 这意味着对于小的仿函数,直接embedded到boost::function
对象中的小缓冲区用于存储仿函数。 对于更大的仿函数,堆将不得不使用新的操作符来获取内存。 在1.34左右的boost 版本中 ,决定采用这种优化 ,因为它可以获得一些非常好的性能优势。
现在,这样一个小缓冲区的合理的(但也许还是很小的)限制是8个字节。 也就是说,我们相当简单的绑定对象不适合小缓冲区,并要求存储新操作符。 如果上面的绑定对象使用了compressed_pair
,那么它实际上可以将其大小减小到8个字节(对于非成员函数指针来说通常是4个字节),因为占位符只不过是一个空对象。
所以,看起来像只是浪费很多字节的东西实际上可能会对性能产生重大影响。
这是存储一对值的标准类。 它被一些标准函数返回/使用,如std::map::insert
。
boost::compressed_pair
宣称效率更高: 见这里
std :: pair在STL中的其他一些容器类中派上用场。
例如:
std::map<> std::multimap<>
两个存储std ::键和值对。
在使用map和multimap的时候,你经常使用指向一个对的指针访问元素。
其他信息:boost :: compressed_pair在这个对的types之一是一个空的结构时是有用的。 这通常用于模板元编程,当这个对的types是从其他types以编程方式推断的。 在那时候,你通常会有某种forms的“空结构”。
我宁愿std :: pair用于任何“正常”使用,除非你进入沉重的模板元编程。
这只不过是一个有两个variables的结构。
我其实不喜欢使用std :: pair函数返回。 代码的读者将不得不知道第一个是什么,第二个是什么。
我有时使用的妥协方法是立即创build常量引用.first和.second,同时明确指定引用。
什么是std :: pair,为什么我会用它?
它就像两个元素一样简单。 在编译器没有广泛支持模板和元编程技术的时候,它被定义在STL的第一个版本中,而这些模板和元编程技术将需要实现Boost.Tuple等更复杂types的元组。
这在许多情况下是有用的。 标准关联容器中使用std::pair
。 它可以用作范围std::pair<iterator, iterator>
的简单forms,所以可以定义接受单个对象表示范围的algorithm,而不是单独的两个迭代器。 (在许多情况下,这是一个有用的select。)
有时候,你总是把两条信息一起传递,无论是作为一个参数,还是一个返回值,或者其他什么。 当然,你可以写自己的对象,但是如果只是两个小的基元或类似的东西,有时候一对就好了。