By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,081 Members | 1,342 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,081 IT Pros & Developers. It's quick & easy.

STL maps and const keys

P: n/a
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>::operator<(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

Jul 19 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
On Wed, 25 Jun 2003 16:49:02 +0100, Michael H Lees
<mh*@cs.nott.ac.uk++> 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>::operator<(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
Jul 19 '05 #2

P: n/a
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>::operator<(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

Jul 19 '05 #3

P: n/a
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

Jul 19 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.