代码之家  ›  专栏  ›  技术社区  ›  Rook

什么是std::pair?

  •  42
  • Rook  · 技术社区  · 16 年前

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

    10 回复  |  直到 16 年前
        1
  •  35
  •   Glorfindel Doug L.    6 年前

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

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

    另外,在书的第1章“tuples”中结帐。 C++标准库扩展:教程和参考文献 作者:皮特·贝克尔,ISBN-13:9780321412997,请详细解释。

    alt text

        2
  •  81
  •   Yamaneko    11 年前

    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 利用这种优化,如果可能,将从对中的一个或另一个类型继承(如果该类型为空)。

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

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

    这意味着如果 FirstType SecondType 你的 pair<A, int> 必须大于 sizeof(int) .

    但是如果你使用 压缩对 ,其生成的代码将类似于:

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

    compressed_pair<A,int> 只有sizeof(int)那么大。

        3
  •  11
  •   David Pierre    16 年前

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

    在这些情况下,这对情侣很方便。

    我认为增强:压缩的_对能够优化掉0大小的成员。 这对于图书馆中的重型模板机械最有用。

    如果您直接控制类型,则与此无关。

        4
  •  11
  •   Johannes Schaub - litb    16 年前

    听到压缩后的_对关心几个字节听起来很奇怪。但是,当考虑到压缩对可以在哪里使用时,它实际上是很重要的。例如,让我们考虑下面的代码:

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

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

    boost::function 鼓励其实现应用小对象优化。这意味着 小的 函数,直接嵌入 Boo::函数 对象用于存储函数。对于较大的函数,必须使用new运算符来使用堆来获取内存。环绕升压 version 1.34 决定采用 this optimization 因为它被认为可以获得一些非常好的性能优势。

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

    所以,仅仅为几个字节浪费大量的思想,实际上可能会对性能产生重大影响。

        5
  •  3
  •   C. K. Young    16 年前

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

    boost::compressed_pair 声称效率更高: see here

        6
  •  3
  •   John Mulder    16 年前

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

    例如:

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

    这两个存储std::键和值对。

    当使用map和multipmap时,通常使用指向对的指针访问元素。

        7
  •  3
  •   rlerallut    16 年前

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

    我更喜欢std::pair用于任何“正常”用途,除非您喜欢使用重型模板元编程。

        8
  •  3
  •   Andrei Taranchenko    16 年前

    它只是一个在引擎盖下有两个变量的结构。

    我实际上不喜欢使用std::pair作为函数返回。代码的读者必须知道什么。第一个是什么,第二个是什么。

    我有时使用的折衷方法是,在清晰地命名引用的同时,立即创建对.first和.second的常量引用。

        9
  •  2
  •   mloskot    13 年前

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

    它和简单的两元素元组一样。它是在第一版的 STL 在编译器不广泛支持模板和元编程技术的时候,这将需要实现更复杂的元组类型 Boost.Tuple .

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

        10
  •  1
  •   Aaron    16 年前

    有时,有两条信息总是一起传递,不管是作为一个参数,还是作为返回值,或者其他什么。当然,您可以编写自己的对象,但如果它只是两个小原语或类似的东西,有时一对看起来就很好了。