std::pair<,>

Discussion in 'C++' started by Neil Zanella, Oct 3, 2003.

  1. Neil Zanella

    Neil Zanella Guest

    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, Oct 3, 2003
    #1
    1. Advertising

  2. Neil Zanella

    Neil Zanella Guest

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

    > Suggestions and reccomendation on the best
    > practices and conventions for using std::pair<,>
    > are most welcome.
    >
    > Thanks,
    >
    > Neil
    >
    >
    Neil Zanella, Oct 3, 2003
    #2
    1. Advertising

  3. > I would like to ask how come the design of C++ includes
    > std::pair.


    I think primarly for std::map and the map-like containers.

    >First of all I don't think many programmers
    > would use it.


    Depends on the programmer, I think. I use it quite
    often.

    >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.


    Yes. std::pair<> was not created specifically to replace
    every ud structs representing two entities.

    > 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<,>.


    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.

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


    There are none, imho.


    Jonathan
    Jonathan Mcdougall, Oct 3, 2003
    #3
  4. Neil Zanella

    Default User Guest

    Neil Zanella wrote:
    >
    > 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.



    I generally use std::make_pair().




    Brian Rodenborn
    Default User, Oct 3, 2003
    #4
  5. Neil Zanella

    David Rubin Guest

    Neil Zanella wrote:
    >
    > 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.


    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
    David Rubin, Oct 3, 2003
    #5
  6. Neil Zanella

    WW Guest

    Neil Zanella wrote:
    > 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;
    > };


    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(Coordinate const &o):
    store(o.store), x(store.first), y(store.second) { }
    Coordinate operator=(Coordinate 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(Coordinate const &o): store(o.store) { }
    Coordinate operator=(Coordinate 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
    WW, Oct 3, 2003
    #6
  7. Neil Zanella

    Mike Wahler Guest

    "Neil Zanella" <> wrote in message
    news:p...
    >
    > Hello,
    >
    > I would like to ask how come the design of C++ includes
    > std::pair.


    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::insert()'
    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.

    > First of all I don't think many programmers
    > would use it.


    I do.

    >For starters, what the first and second
    > members are depends on what you are using the pair
    > for.


    Well of course.

    >For instance if I am using coordinates in two
    > dimensional space then I like to use x and y.


    But what are their types? Are the types the same?
    The already existing template 'std::pair' will
    handle them whatever they are.

    > 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.


    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.

    >
    > 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++.


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


    >The only way I can think
    > of is to subclass std::pair<,>.


    IMO no reason to.

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

    Done. :)

    Also see 'std::make_pair()'


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


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

    -Mike
    Mike Wahler, Oct 3, 2003
    #7
  8. Neil Zanella

    David Rubin Guest

    Mike Wahler wrote:

    > > 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++.

    [snip]
    > >The only way I can think
    > > of is to subclass std::pair<,>.

    >
    > IMO no reason to.
    >
    > std::pair<T,T>(x,y);


    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
    David Rubin, Oct 3, 2003
    #8
  9. Neil Zanella

    David Rubin Guest

    David Rubin wrote:

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


    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
    David Rubin, Oct 3, 2003
    #9
  10. Neil Zanella

    Mike Wahler Guest

    "David Rubin" <> wrote in message
    news:...
    > Mike Wahler wrote:
    >
    > > > 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++.

    > [snip]
    > > >The only way I can think
    > > > of is to subclass std::pair<,>.

    > >
    > > IMO no reason to.
    > >
    > > std::pair<T,T>(x,y);

    >
    > The question is, is a Point a pair? From the description of pair, it
    > seems like the answer is yes.


    Agreed.

    > So, if you want a Point with members x and
    > y, why not subclass?


    Why not simply:

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

    or if you like:

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

    Point coord(x,y);

    ??

    -Mike
    Mike Wahler, Oct 3, 2003
    #10
  11. > > So, if you want a Point with members x and
    > > y, why not subclass?

    >
    > Why not simply:
    >
    > std::pair<int,int> coord(x,y);
    >
    > or if you like:
    >
    > typedef std::pair<int,int> Point;
    >
    > Point coord(x,y);


    The thig is

    coord.first = 2;

    is not quite representative, as opposed to

    coord.x = 2;


    Jonathan
    Jonathan Mcdougall, Oct 4, 2003
    #11
  12. Neil Zanella

    WW Guest

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

    >
    > 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?


    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
    WW, Oct 4, 2003
    #12
  13. Neil Zanella

    Mike Wahler Guest

    "Jonathan Mcdougall" <> wrote in message
    news:mrpfb.37030$...
    > > > So, if you want a Point with members x and
    > > > y, why not subclass?

    > >
    > > Why not simply:
    > >
    > > std::pair<int,int> coord(x,y);
    > >
    > > or if you like:
    > >
    > > typedef std::pair<int,int> Point;
    > >
    > > Point coord(x,y);

    >
    > The thig is
    >
    > coord.first = 2;
    >
    > is not quite representative, as opposed to
    >
    > coord.x = 2;


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

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

    -Mike
    Mike Wahler, Oct 4, 2003
    #13
  14. Neil Zanella

    Neil Zanella Guest

    "Jonathan Mcdougall" <> wrote in message

    > The thing is
    >
    > coord.first = 2;
    >
    > is not quite representative, as opposed to
    >
    > coord.x = 2;
    >
    > Jonathan


    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
    Neil Zanella, Oct 4, 2003
    #14
  15. Neil Zanella

    Cy Edmunds Guest

    "WW" <> wrote in message
    news:blkogv$l83$...
    > Neil Zanella wrote:
    > > 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;
    > > };

    >
    > 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(Coordinate const &o):
    > store(o.store), x(store.first), y(store.second) { }
    > Coordinate operator=(Coordinate 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(Coordinate const &o): store(o.store) { }
    > Coordinate operator=(Coordinate 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
    >
    >


    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
    http://home.rochester.rr.com/cyhome/
    Cy Edmunds, Oct 6, 2003
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Eric Lilja
    Replies:
    5
    Views:
    712
    Eric Lilja
    Mar 4, 2005
  2. Mark P

    std::pair allocator?

    Mark P, Apr 27, 2005, in forum: C++
    Replies:
    6
    Views:
    1,254
    Rolf Magnus
    Apr 27, 2005
  3. Bart Simpson
    Replies:
    6
    Views:
    374
    Diego Martins
    Mar 13, 2006
  4. desktop

    Using std:.pair right

    desktop, Jun 16, 2007, in forum: C++
    Replies:
    18
    Views:
    535
    Andrew Koenig
    Jun 18, 2007
  5. Replies:
    3
    Views:
    373
    James Kanze
    Dec 21, 2007
Loading...

Share This Page