std::pair<,>

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Neil Zanella

    std::pair<,>


    Hello,

    I would like to ask how come the design of C++ includes
    std::pair. First of all I don't think many programmers
    would use it. For starters, what the first and second
    members are depends on what you are using the pair
    for. For instance if I am using coordinates in two
    dimensional space then I like to use x and y. So
    I might as well define my own struct with x and
    y members in it and create a constructor so
    that I can easily instantiate pairs.

    I wonder if there is a way to create a pair class
    using std::pair but typedef its first and second
    to x and y using C++. The only way I can think
    of is to subclass std::pair<,>.

    Suggestions and reccomendation on the best
    practices and conventions for using std::pair<,>
    are most welcome.

    Thanks,

    Neil

  • Neil Zanella

    #2
    Re: std::pair&lt;,& gt;


    Here is my way of making use of std::pair<class T1, class T2>:

    #include <iostream>
    #include <utility>

    template<class T1, class T2>
    class Coordinate: public std::pair<T1, T2> {
    public:
    Coordinate(T1 x, T2 y): std::pair<T1, T2>(x, y), x(first), y(second) { }
    T1 &x;
    T2 &y;
    };

    int main() {
    Coordinate<int, int> foo(1, 2);
    std::cout << "x = " << foo.x << "\ny = " << foo.y << std::endl;
    }
    [color=blue]
    > Suggestions and reccomendation on the best
    > practices and conventions for using std::pair<,>
    > are most welcome.
    >
    > Thanks,
    >
    > Neil
    >
    >[/color]

    Comment

    • Jonathan Mcdougall

      #3
      Re: std::pair&lt;,& gt;

      > I would like to ask how come the design of C++ includes[color=blue]
      > std::pair.[/color]

      I think primarly for std::map and the map-like containers.
      [color=blue]
      >First of all I don't think many programmers
      > would use it.[/color]

      Depends on the programmer, I think. I use it quite
      often.
      [color=blue]
      >For starters, what the first and second
      > members are depends on what you are using the pair
      > for. For instance if I am using coordinates in two
      > dimensional space then I like to use x and y. So
      > I might as well define my own struct with x and
      > y members in it and create a constructor so
      > that I can easily instantiate pairs.[/color]

      Yes. std::pair<> was not created specifically to replace
      every ud structs representing two entities.
      [color=blue]
      > I wonder if there is a way to create a pair class
      > using std::pair but typedef its first and second
      > to x and y using C++. The only way I can think
      > of is to subclass std::pair<,>.[/color]

      That would be one way if you want your struct to be
      compatible with std::pair<>. If not, make it
      a private member or, as you said, create a new
      struct.
      [color=blue]
      > Suggestions and reccomendation on the best
      > practices and conventions for using std::pair<,>
      > are most welcome.[/color]

      There are none, imho.


      Jonathan


      Comment

      • Default User

        #4
        Re: std::pair&lt;,& gt;

        Neil Zanella wrote:[color=blue]
        >
        > Hello,
        >
        > I would like to ask how come the design of C++ includes
        > std::pair. First of all I don't think many programmers
        > would use it.[/color]


        I generally use std::make_pair( ).




        Brian Rodenborn

        Comment

        • David Rubin

          #5
          Re: std::pair&lt;,& gt;

          Neil Zanella wrote:[color=blue]
          >
          > Hello,
          >
          > I would like to ask how come the design of C++ includes
          > std::pair. First of all I don't think many programmers
          > would use it. For starters, what the first and second
          > members are depends on what you are using the pair
          > for. For instance if I am using coordinates in two
          > dimensional space then I like to use x and y. So
          > I might as well define my own struct with x and
          > y members in it and create a constructor so
          > that I can easily instantiate pairs.
          >
          > I wonder if there is a way to create a pair class
          > using std::pair but typedef its first and second
          > to x and y using C++. The only way I can think
          > of is to subclass std::pair<,>.
          >
          > Suggestions and reccomendation on the best
          > practices and conventions for using std::pair<,>
          > are most welcome.[/color]

          I think you can start by doing something like

          template <typename T>
          class Point : public std::pair<T,T>
          {
          public:
          T& x,y;
          Point(const T& a, const T& b) : std::pair<T,T>( a,b), x(first),
          y(second) {}
          /* ... */
          };

          This gives you more of a pointy interface while also modeling a
          container.

          /david

          --
          Andre, a simple peasant, had only one thing on his mind as he crept
          along the East wall: 'Andre, creep... Andre, creep... Andre, creep.'
          -- unknown

          Comment

          • WW

            #6
            Re: std::pair&lt;,& gt;

            Neil Zanella wrote:[color=blue]
            > Here is my way of making use of std::pair<class T1, class T2>:
            >
            > #include <iostream>
            > #include <utility>
            >
            > template<class T1, class T2>
            > class Coordinate: public std::pair<T1, T2> {
            > public:
            > Coordinate(T1 x, T2 y): std::pair<T1, T2>(x, y), x(first),
            > y(second) { } T1 &x;
            > T2 &y;
            > };[/color]

            The above class cannot be assigned, or copy constructed. Plus: do not use
            inheritance when composition suffices:

            template<class T1, class T2>
            struct Coordinate {
            Coordinate():
            store(T1(),T2() ), x(store.first), y(store.second) { }
            Coordinate(T1 px, T2 py):
            store(px,py), x(store.first), y(store.second) { }
            Coordinate(Coor dinate const &o):
            store(o.store), x(store.first), y(store.second) { }
            Coordinate operator=(Coord inate const &o)
            { store = o.store; }
            T1 &x;
            T2 &y;
            private:
            std::pair<T1, T2> store;
            };

            Also note that the above class will be bigger than the pair. In case of
            int, on a usual architecture it will be twice as big. So IMHO you are
            better off having accessor functions - if you must access the elements from
            the outside.

            template<class T1, class T2>
            struct Coordinate {
            Coordinate(): store(T1(),T2() ) { }
            Coordinate(T1 px, T2 py): store(px,py) { }
            Coordinate(Coor dinate const &o): store(o.store) { }
            Coordinate operator=(Coord inate const &o) { store = o.store; }
            T1 &x() {return store.first; }
            T2 &y() {return store.second; }
            private:
            std::pair<T1, T2> store;
            };

            But to be honest I would just leave std::pair out of this completely and
            make a little template struct of my own, with the right names.

            --
            WW aka Attila


            Comment

            • Mike Wahler

              #7
              Re: std::pair&lt;,& gt;

              "Neil Zanella" <nzanella@cs.mu n.ca> wrote in message
              news:Pine.LNX.4 .44.03100315370 40.23774-100000@garfield .cs.mun.ca...[color=blue]
              >
              > Hello,
              >
              > I would like to ask how come the design of C++ includes
              > std::pair.[/color]

              It's useful for some things. If you don't find it
              useful, don't use it.

              Also note that the standard container types 'std::map'
              and 'std::multimap' use type 'std::pair' objects to represent
              their elements. If you use a map or multimap, you're
              (at least indirectly) using 'std::pair' objects.
              Also e.g. one of the overloads of 'std::map::inse rt()'
              returns a 'std::pair' object (not an element value,
              but a pair of values, the first of which is an iterator
              object pointing to the inserted element (if one was inserted),
              and the other a type 'bool' indicating whether or not
              the insertion occurred.)

              'std::pair' can also be used as a 'general purpose'
              set of two values.
              [color=blue]
              > First of all I don't think many programmers
              > would use it.[/color]

              I do.
              [color=blue]
              >For starters, what the first and second
              > members are depends on what you are using the pair
              > for.[/color]

              Well of course.
              [color=blue]
              >For instance if I am using coordinates in two
              > dimensional space then I like to use x and y.[/color]

              But what are their types? Are the types the same?
              The already existing template 'std::pair' will
              handle them whatever they are.
              [color=blue]
              > So
              > I might as well define my own struct with x and
              > y members in it and create a constructor so
              > that I can easily instantiate pairs.[/color]

              This can already be done with 'std::pair', which
              has three constructors defined (one of them a
              template). "Don't reinvent the wheel" and all that.
              [color=blue]
              >
              > I wonder if there is a way to create a pair class
              > using std::pair but typedef its first and second
              > to x and y using C++.[/color]

              Are 'x' and 'y' types or values? In either case,
              std::pair can handle it.

              [color=blue]
              >The only way I can think
              > of is to subclass std::pair<,>.[/color]

              IMO no reason to.

              std::pair<T,T>( x,y);

              Done. :-)

              Also see 'std::make_pair ()'

              [color=blue]
              >
              > Suggestions and reccomendation on the best
              > practices and conventions for using std::pair<,>
              > are most welcome.[/color]

              Use it if useful, don't use it if not.

              -Mike


              Comment

              • David Rubin

                #8
                Re: std::pair&lt;,& gt;

                Mike Wahler wrote:
                [color=blue][color=green]
                > > I wonder if there is a way to create a pair class
                > > using std::pair but typedef its first and second
                > > to x and y using C++.[/color][/color]
                [snip][color=blue][color=green]
                > >The only way I can think
                > > of is to subclass std::pair<,>.[/color]
                >
                > IMO no reason to.
                >
                > std::pair<T,T>( x,y);[/color]

                The question is, is a Point a pair? From the description of pair, it
                seems like the answer is yes. So, if you want a Point with members x and
                y, why not subclass?

                /david

                --
                Andre, a simple peasant, had only one thing on his mind as he crept
                along the East wall: 'Andre, creep... Andre, creep... Andre, creep.'
                -- unknown

                Comment

                • David Rubin

                  #9
                  Re: std::pair&lt;,& gt;

                  David Rubin wrote:

                  [snip][color=blue]
                  > This gives you more of a pointy interface while also modeling a
                  > container.[/color]

                  Not true; std::pair does not model a Container.

                  /david

                  --
                  Andre, a simple peasant, had only one thing on his mind as he crept
                  along the East wall: 'Andre, creep... Andre, creep... Andre, creep.'
                  -- unknown

                  Comment

                  • Mike Wahler

                    #10
                    Re: std::pair&lt;,& gt;


                    "David Rubin" <bogus_address@ nomail.com> wrote in message
                    news:3F7DF018.9 637D997@nomail. com...[color=blue]
                    > Mike Wahler wrote:
                    >[color=green][color=darkred]
                    > > > I wonder if there is a way to create a pair class
                    > > > using std::pair but typedef its first and second
                    > > > to x and y using C++.[/color][/color]
                    > [snip][color=green][color=darkred]
                    > > >The only way I can think
                    > > > of is to subclass std::pair<,>.[/color]
                    > >
                    > > IMO no reason to.
                    > >
                    > > std::pair<T,T>( x,y);[/color]
                    >
                    > The question is, is a Point a pair? From the description of pair, it
                    > seems like the answer is yes.[/color]

                    Agreed.
                    [color=blue]
                    > So, if you want a Point with members x and
                    > y, why not subclass?[/color]

                    Why not simply:

                    std::pair<int,i nt> coord(x,y);

                    or if you like:

                    typedef std::pair<int,i nt> Point;

                    Point coord(x,y);

                    ??

                    -Mike


                    Comment

                    • Jonathan Mcdougall

                      #11
                      Re: std::pair&lt;,& gt;

                      > > So, if you want a Point with members x and[color=blue][color=green]
                      > > y, why not subclass?[/color]
                      >
                      > Why not simply:
                      >
                      > std::pair<int,i nt> coord(x,y);
                      >
                      > or if you like:
                      >
                      > typedef std::pair<int,i nt> Point;
                      >
                      > Point coord(x,y);[/color]

                      The thig is

                      coord.first = 2;

                      is not quite representative, as opposed to

                      coord.x = 2;


                      Jonathan


                      Comment

                      • WW

                        #12
                        Re: std::pair&lt;,& gt;

                        David Rubin wrote:[color=blue][color=green]
                        >> std::pair<T,T>( x,y);[/color]
                        >
                        > The question is, is a Point a pair? From the description of pair, it
                        > seems like the answer is yes. So, if you want a Point with members x
                        > and y, why not subclass?[/color]

                        A point is not a pair. A point can be in 1 or 2 dimensions. A pair is
                        always a pair. They do look similar, but that is all.

                        --
                        WW aka Attila


                        Comment

                        • Mike Wahler

                          #13
                          Re: std::pair&lt;,& gt;


                          "Jonathan Mcdougall" <jonathanmcdoug all@DELyahoo.ca > wrote in message
                          news:mrpfb.3703 0$yV2.747489@we ber.videotron.n et...[color=blue][color=green][color=darkred]
                          > > > So, if you want a Point with members x and
                          > > > y, why not subclass?[/color]
                          > >
                          > > Why not simply:
                          > >
                          > > std::pair<int,i nt> coord(x,y);
                          > >
                          > > or if you like:
                          > >
                          > > typedef std::pair<int,i nt> Point;
                          > >
                          > > Point coord(x,y);[/color]
                          >
                          > The thig is
                          >
                          > coord.first = 2;
                          >
                          > is not quite representative, as opposed to
                          >
                          > coord.x = 2;[/color]

                          Ah, ok I misunderstood. He wants specific member
                          names.

                          "Ne-e-e-e-e-ver Mind!"
                          -Gilda Radner

                          -Mike


                          Comment

                          • Neil Zanella

                            #14
                            Re: std::pair&lt;,& gt;

                            "Jonathan Mcdougall" <jonathanmcdoug all@DELyahoo.ca > wrote in message
                            [color=blue]
                            > The thing is
                            >
                            > coord.first = 2;
                            >
                            > is not quite representative, as opposed to
                            >
                            > coord.x = 2;
                            >
                            > Jonathan[/color]

                            That was exactly my point. As other posters have pointed out, there is a
                            function called std::make_pair( ,) but that does not improve things much. Rather,
                            the main purpose of std::pair in the STL is so that in an associative container
                            such as an std::map or std::multimap you can use the .first notation to access
                            the key stored for a particular value (also accessed with .second). This is
                            quite handy since if you're iterating over a map you will need .first
                            to access the keys, and .second to access the values.

                            So, in conclusion, when dealing with points in two dimensional space (or other
                            dimensions for that matter) it's not very nice to use std::pair: that's not
                            what it was meant to. I don't think std::pair supports arithmetical operations
                            on points, and besides, using first and second instead of something like x and
                            y leads to poor naming. The names first and second are not suitable for all
                            applications from a semantical point of view: they make things harder to
                            interpret. The real use of std::pair is for providing first and second
                            to std::map and std::multimap.

                            Regards,

                            Neil

                            Comment

                            • Cy Edmunds

                              #15
                              Re: std::pair&lt;,& gt;

                              "WW" <wolof@freemail .hu> wrote in message
                              news:blkogv$l83 $1@phys-news1.kolumbus. fi...[color=blue]
                              > Neil Zanella wrote:[color=green]
                              > > Here is my way of making use of std::pair<class T1, class T2>:
                              > >
                              > > #include <iostream>
                              > > #include <utility>
                              > >
                              > > template<class T1, class T2>
                              > > class Coordinate: public std::pair<T1, T2> {
                              > > public:
                              > > Coordinate(T1 x, T2 y): std::pair<T1, T2>(x, y), x(first),
                              > > y(second) { } T1 &x;
                              > > T2 &y;
                              > > };[/color]
                              >
                              > The above class cannot be assigned, or copy constructed. Plus: do not use
                              > inheritance when composition suffices:
                              >
                              > template<class T1, class T2>
                              > struct Coordinate {
                              > Coordinate():
                              > store(T1(),T2() ), x(store.first), y(store.second) { }
                              > Coordinate(T1 px, T2 py):
                              > store(px,py), x(store.first), y(store.second) { }
                              > Coordinate(Coor dinate const &o):
                              > store(o.store), x(store.first), y(store.second) { }
                              > Coordinate operator=(Coord inate const &o)
                              > { store = o.store; }
                              > T1 &x;
                              > T2 &y;
                              > private:
                              > std::pair<T1, T2> store;
                              > };
                              >
                              > Also note that the above class will be bigger than the pair. In case of
                              > int, on a usual architecture it will be twice as big. So IMHO you are
                              > better off having accessor functions - if you must access the elements[/color]
                              from[color=blue]
                              > the outside.
                              >
                              > template<class T1, class T2>
                              > struct Coordinate {
                              > Coordinate(): store(T1(),T2() ) { }
                              > Coordinate(T1 px, T2 py): store(px,py) { }
                              > Coordinate(Coor dinate const &o): store(o.store) { }
                              > Coordinate operator=(Coord inate const &o) { store = o.store; }
                              > T1 &x() {return store.first; }
                              > T2 &y() {return store.second; }
                              > private:
                              > std::pair<T1, T2> store;
                              > };
                              >
                              > But to be honest I would just leave std::pair out of this completely and
                              > make a little template struct of my own, with the right names.
                              >
                              > --
                              > WW aka Attila
                              >
                              >[/color]

                              This thread is kind of an unintentional parody of going massively overboard
                              with reuse. Perhaps you should ask yourselves why the designers of the
                              standard library didn't derive std::complex from std::pair. The answer: they
                              weren't nuts. lol

                              If you want a class with an x and a y, just write one from scratch. It's
                              about 10 lines of code depending on how you format it. And anybody will be
                              able to understand it in a glance without wondering why you were standing on
                              your head to reuse std::pair.

                              --
                              Cy



                              Comment

                              Working...