STL maps and const keys

M

Michael H Lees

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
 
T

tom_usenet

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
 
T

Thomas Matthews

Michael said:
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
 
T

Thomas Matthews

Michael said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

_BLOCK_TYPE_IS_VALID assertion with maps 0
Modify STL multiset 2
matrix mult with const in c++ 0
Exceptions in class 7
problems with stl maps 3
STL hash_map 1
Problem with STL sort. 3
operator[] for maps 3

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top