STL maps and const keys

Discussion in 'C++' started by Michael H Lees, Jun 25, 2003.

  1. Hi there,

    I'm trying to use an stl map where I have my own defined (templated)
    class as a key. I have the class "variableId" below which I want to use
    as the key for an stl map. It has two members agent and slot. I've
    defined the < operator but I'm slightly confused, here's the complete
    class anyhow,

    template <typename agentId, typename slotId>
    class variableId
    {
    public:
    agentId agent;
    slotId slot;
    variableId(){}
    variableId(agentId aId, slotId sId);
    bool operator<(variableId vId);
    };

    template <typename agentId, typename slotId>
    variableId<agentId,slotId>::variableId(agentId aId, slotId sId)
    {
    agent=aId;
    slot=sId;
    }

    template <typename agentId, typename slotId>
    bool variableId<agentId,slotId>::
    operator< (variableId vId)
    {
    return (slot<vId.slot && agent<vId.agent);
    }


    When I then try and do something like...

    map<variableId<int,int>,int> m;
    variableId<int,int> varname(1,1);
    m[varname] = 1;


    I get gcc reporting an error on the line m[varname]=1, something like

    /usr/local/include/g++-v3/bits/stl_function.h:141: passing `const
    variableId<int, int>' as `this' argument of `bool variableId<agentId,
    slotId>::eek:perator<(variableId<agentId, slotId>) [with agentId = int,
    slotId = int]' discards qualifiers

    I guess I'm either calling incorrecty or I've specified the
    class/operator incorrectly.


    Any help much appreciated


    Thanks

    ps. remove ++ from address to reply
    Michael H Lees, Jun 25, 2003
    #1
    1. Advertising

  2. Michael H Lees

    tom_usenet Guest

    On Wed, 25 Jun 2003 16:49:02 +0100, Michael H Lees
    <++> wrote:

    >Hi there,
    >
    >I'm trying to use an stl map where I have my own defined (templated)
    >class as a key. I have the class "variableId" below which I want to use
    >as the key for an stl map. It has two members agent and slot. I've
    >defined the < operator but I'm slightly confused, here's the complete
    >class anyhow,
    >
    >template <typename agentId, typename slotId>
    >class variableId
    >{
    >public:
    > agentId agent;
    > slotId slot;
    > variableId(){}
    > variableId(agentId aId, slotId sId);
    > bool operator<(variableId vId);


    Should be:
    bool operator<(variableId vId) const;
    or
    bool operator<(variableId const& vId) const;

    >};
    >
    >template <typename agentId, typename slotId>
    >variableId<agentId,slotId>::variableId(agentId aId, slotId sId)
    >{
    > agent=aId;
    > slot=sId;
    >}
    >
    >template <typename agentId, typename slotId>
    >bool variableId<agentId,slotId>::
    >operator< (variableId vId)
    > {
    > return (slot<vId.slot && agent<vId.agent);
    > }


    template <typename agentId, typename slotId>
    bool variableId<agentId,slotId>::
    operator< (variableId vId) const
    {
    return (slot<vId.slot && agent<vId.agent);
    }

    or

    template <typename agentId, typename slotId>
    bool variableId<agentId,slotId>::
    operator< (variableId const& vId) const
    {
    return (slot<vId.slot && agent<vId.agent);
    }


    >
    >
    >When I then try and do something like...
    >
    > map<variableId<int,int>,int> m;
    > variableId<int,int> varname(1,1);
    > m[varname] = 1;


    That's fine.

    >
    >
    >I get gcc reporting an error on the line m[varname]=1, something like
    >
    >/usr/local/include/g++-v3/bits/stl_function.h:141: passing `const
    >variableId<int, int>' as `this' argument of `bool variableId<agentId,
    >slotId>::eek:perator<(variableId<agentId, slotId>) [with agentId = int,
    >slotId = int]' discards qualifiers


    Right, you need a const operator since the key in a map is const.

    >
    >I guess I'm either calling incorrecty or I've specified the
    >class/operator incorrectly.


    The latter.

    Tom
    tom_usenet, Jun 25, 2003
    #2
    1. Advertising

  3. Michael H Lees wrote:
    > Hi there,
    >
    > I'm trying to use an stl map where I have my own defined (templated)
    > class as a key. I have the class "variableId" below which I want to use
    > as the key for an stl map. It has two members agent and slot. I've
    > defined the < operator but I'm slightly confused, here's the complete
    > class anyhow,
    >
    > template <typename agentId, typename slotId>
    > class variableId
    > {
    > public:
    > agentId agent;
    > slotId slot;
    > variableId(){}
    > variableId(agentId aId, slotId sId);
    > bool operator<(variableId vId);


    bool operator<(const variableId& vId) const;

    > };
    >
    > template <typename agentId, typename slotId>
    > variableId<agentId,slotId>::variableId(agentId aId, slotId sId)

    : agent(aId), slot(sId) // prefer initialization lists.

    > {
    > agent=aId;
    > slot=sId;
    > }


    The above assignments should be replaced by the
    initialization list above.



    >
    > template <typename agentId, typename slotId>
    > bool variableId<agentId,slotId>::
    > operator< (variableId vId)


    operator< (const variableId& vId) const

    > {
    > return (slot<vId.slot && agent<vId.agent);

    // Perhaps some spaces would improve readability:
    // (also, return is not a function and doesn't require
    // an expression in parenthesis).
    return (slot < vId.slot) && (agent < vId.agent);

    > }
    >
    >
    > When I then try and do something like...
    >
    > map<variableId<int,int>,int> m;
    > variableId<int,int> varname(1,1);
    > m[varname] = 1;
    >
    >
    > I get gcc reporting an error on the line m[varname]=1, something like
    >
    > /usr/local/include/g++-v3/bits/stl_function.h:141: passing `const
    > variableId<int, int>' as `this' argument of `bool variableId<agentId,
    > slotId>::eek:perator<(variableId<agentId, slotId>) [with agentId = int,
    > slotId = int]' discards qualifiers
    >
    > I guess I'm either calling incorrecty or I've specified the
    > class/operator incorrectly.
    >
    >
    > Any help much appreciated
    >
    >
    > Thanks
    >
    > ps. remove ++ from address to reply
    >


    Add the "const" qualifiers to the "operator <" method above.
    The key of a map is constant, but the comparison function wasn't.


    --
    Thomas Matthews

    C++ newsgroup welcome message:
    http://www.slack.net/~shiva/welcome.txt
    C++ Faq: http://www.parashift.com/c -faq-lite
    C Faq: http://www.eskimo.com/~scs/c-faq/top.html
    alt.comp.lang.learn.c-c++ faq:
    http://www.raos.demon.uk/acllc-c /faq.html
    Other sites:
    http://www.josuttis.com -- C++ STL Library book
    Thomas Matthews, Jun 25, 2003
    #3
  4. Michael H Lees wrote:
    > Replying to my own question.... I know.
    >
    > I managed to fix the problem by looking at stl::pair as an example.
    >
    > I redefined the < operator as follows.....
    >
    > template <class agentId, class slotId>
    > inline bool operator<(const variableId<agentId, slotId>& v1,
    > const variableId<agentId, slotId>& v2)
    > {
    > return (v1.slot<v2.slot && v1.agent<v2.agent);
    > }
    >
    > I had tried all manner of things but missed the inline option. Should I
    > define all my operators as inline if I'm using the class as a key for a
    > map?
    >
    > Cheers
    >
    > _mike_
    >

    1. Don't top-post. Replies are either intermixed or appended to
    the bottom of a post.
    2. A rule of thumb of inlining: Inline simple functions. A get or
    a set method is an example. If the overhead of the function
    call is greater than the code in the function, then inline the
    function.

    --
    Thomas Matthews

    C++ newsgroup welcome message:
    http://www.slack.net/~shiva/welcome.txt
    C++ Faq: http://www.parashift.com/c -faq-lite
    C Faq: http://www.eskimo.com/~scs/c-faq/top.html
    alt.comp.lang.learn.c-c++ faq:
    http://www.raos.demon.uk/acllc-c /faq.html
    Other sites:
    http://www.josuttis.com -- C++ STL Library book
    Thomas Matthews, Jun 26, 2003
    #4
    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. Simon Elliott
    Replies:
    4
    Views:
    1,146
    Simon Elliott
    Mar 10, 2005
  2. Marcus
    Replies:
    2
    Views:
    579
    Marcus
    Dec 9, 2005
  3. Replies:
    11
    Views:
    1,089
  4. Javier
    Replies:
    2
    Views:
    547
    James Kanze
    Sep 4, 2007
  5. 0m
    Replies:
    26
    Views:
    1,095
    Tim Rentsch
    Nov 10, 2008
Loading...

Share This Page