STL maps and const keys

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Michael H Lees

    STL maps and const keys

    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(agen tId aId, slotId sId);
    bool operator<(varia bleId vId);
    };

    template <typename agentId, typename slotId>
    variableId<agen tId,slotId>::va riableId(agentI d aId, slotId sId)
    {
    agent=aId;
    slot=sId;
    }

    template <typename agentId, typename slotId>
    bool variableId<agen tId,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<agen tId,
    slotId>::operat or<(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

  • tom_usenet

    #2
    Re: STL maps and const keys

    On Wed, 25 Jun 2003 16:49:02 +0100, Michael H Lees
    <mhl@cs.nott.ac .uk++> wrote:
    [color=blue]
    >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(agen tId aId, slotId sId);
    > bool operator<(varia bleId vId);[/color]

    Should be:
    bool operator<(varia bleId vId) const;
    or
    bool operator<(varia bleId const& vId) const;
    [color=blue]
    >};
    >
    >template <typename agentId, typename slotId>
    >variableId<age ntId,slotId>::v ariableId(agent Id aId, slotId sId)
    >{
    > agent=aId;
    > slot=sId;
    >}
    >
    >template <typename agentId, typename slotId>
    >bool variableId<agen tId,slotId>::
    >operator< (variableId vId)
    > {
    > return (slot<vId.slot && agent<vId.agent );
    > }[/color]

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

    or

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

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

    That's fine.
    [color=blue]
    >
    >
    >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<agen tId,
    >slotId>::opera tor<(variableId <agentId, slotId>) [with agentId = int,
    >slotId = int]' discards qualifiers[/color]

    Right, you need a const operator since the key in a map is const.
    [color=blue]
    >
    >I guess I'm either calling incorrecty or I've specified the
    >class/operator incorrectly.[/color]

    The latter.

    Tom

    Comment

    • Thomas Matthews

      #3
      Re: STL maps and const keys

      Michael H Lees wrote:[color=blue]
      > 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(agen tId aId, slotId sId);
      > bool operator<(varia bleId vId);[/color]

      bool operator<(const variableId& vId) const;
      [color=blue]
      > };
      >
      > template <typename agentId, typename slotId>
      > variableId<agen tId,slotId>::va riableId(agentI d aId, slotId sId)[/color]
      : agent(aId), slot(sId) // prefer initialization lists.
      [color=blue]
      > {
      > agent=aId;
      > slot=sId;
      > }[/color]

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


      [color=blue]
      >
      > template <typename agentId, typename slotId>
      > bool variableId<agen tId,slotId>::
      > operator< (variableId vId)[/color]

      operator< (const variableId& vId) const
      [color=blue]
      > {
      > return (slot<vId.slot && agent<vId.agent );[/color]
      // 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);
      [color=blue]
      > }
      >
      >
      > 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<agen tId,
      > slotId>::operat or<(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
      >[/color]

      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:

      C++ Faq: http://www.parashift.com/c++-faq-lite
      C Faq: http://www.eskimo.com/~scs/c-faq/top.html
      alt.comp.lang.l earn.c-c++ faq:

      Other sites:
      http://www.josuttis.com -- C++ STL Library book

      Comment

      • Thomas Matthews

        #4
        Re: STL maps and const keys

        Michael H Lees wrote:[color=blue]
        > 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<agen tId, slotId>& v1,
        > const variableId<agen tId, slotId>& v2)
        > {
        > return (v1.slot<v2.slo t && v1.agent<v2.age nt);
        > }
        >
        > 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_
        >[/color]
        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:

        C++ Faq: http://www.parashift.com/c++-faq-lite
        C Faq: http://www.eskimo.com/~scs/c-faq/top.html
        alt.comp.lang.l earn.c-c++ faq:

        Other sites:
        http://www.josuttis.com -- C++ STL Library book

        Comment

        Working...