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

有帮助吗?

解决方案

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

当你学习的时候 pair, ,你可以看看 tuple. 。就像是 pair 但用于对任意数量的值进行分组。 tuple 是 TR1 的一部分,许多编译器已将其包含在其标准库实现中。

另外,请查看本书的第一章“元组” C++ 标准库扩展:教程和参考 作者:皮特·贝克尔,ISBN-13:9780321412997,详细解释。

alt text

其他提示

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; };

在这里,很好 BC 具有相同的尺寸,即使 sizeof(A) 不可能为零。

所以 boost::compressed_pair 利用此优化,并在可能的情况下从该对中的一个或另一个类型(如果该类型为空)继承。

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

template<typename FirstType, typename SecondType>
struct pair {
   FirstType first;
   SecondType second;
};

这意味着如果 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_; }
 };

compressed_pair<A,int> 只会与 sizeof(int) 一样大。

有时您需要从函数返回 2 个值,而为此创建一个类通常是多余的。

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

我认为 boost:compressed_pa​​ir 能够优化掉大小为 0 的成员。这对于图书馆中的重型模板机械最有用。

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

听到压缩对关心几个字节听起来很奇怪。但当人们考虑在哪里可以使用compressed_pa​​ir时,它实际上很重要。例如,让我们考虑一下这段代码:

boost::function<void(int)> f(boost::bind(&f, _1));

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

boost::function 鼓励其实现应用小对象优化。这意味着对于 小的 函子,一个直接嵌入到的小缓冲区 boost::function 对象用于存储函子。对于较大的函子,必须通过使用运算符 new 来使用堆来获取内存。周围升压 1.34版, ,决定采用 本次优化, ,因为人们认为可以获得一些非常好的性能优势。

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

因此,看似仅仅为了几个字节而浪费大量思考实际上可能会对性能产生重大影响。

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

boost::compressed_pair 声称更高效: 看这里

std::pair 对于 STL 中的其他几个容器类非常有用。

例如:

std::map<>
std::multimap<> 

两者都存储 std:: 键和值对。

使用映射和多重映射时,您经常使用指向对的指针来访问元素。

附加信息:当对的类型之一是空结构时, boost::compressed_pa​​ir 很有用。当以编程方式从其他类型推断出对的类型时,这通常在模板元编程中使用。最后,您通常会得到某种形式的“空结构”。

我更喜欢 std::pair 进行任何“正常”使用,除非您喜欢繁重的模板元编程。

它只不过是一个在幕后有两个变量的结构。

我实际上不喜欢使用 std::pair 来返回函数。代码的读者必须知道什么是 .first 和什么是 .second。

我有时使用的折衷方案是立即创建对 .first 和 .second 的常量引用,同时明确命名引用。

std::pair 的用途是什么,为什么要使用它?

它就像简单的两个元素元组一样。它是在第一个版本中定义的 STL 当编译器没有广泛支持模板和元编程技术时,需要实现更复杂的元组类型,例如 Boost元组.

它在很多情况下都很有用。 std::pair 用于标准关联容器。它可以用作范围的简单形式 std::pair<iterator, iterator> - 因此可以定义接受表示范围的单个对象而不是分别接受两个迭代器的算法。(在许多情况下这是一个有用的替代方案。)

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top