Problem using std::map

K

kamaraj80

Hi
I am using the std:: map as following.

typedef struct _SeatRowCols
{
long nSeatRow;
unsigned char ucSeatLetter;
}SeatRowCols;

typedef struct _NetData
{
SeatRowCols tSeatRowCols;
unsigned char ucMacAddress[MAC_LENGTH];
unsigned char ucAdminStatus;
unsigned char ucLocalFault;

}NetData;

typedef std::map <SeatRowCols, PedData> MAP_PED_DATA;
..........
.............

MAP_PED_DATA data;
PedData pdata;
SeatRowCols sdata;

memset((void*)&sdata,0,sizeof(SeatRowCols));
sdata.nSeatRow =1;
sdata.ucSeatLetter ='A';
memset((void*)&pdata,0,sizeof(PedData));
pdata.nPortClass = 1;
pdata.tSeatRowCols = sdata;
data[sdata] = pdata;

while compiling this code the following error are occurs.

Compiling...
DemoOfDatatStructures.cpp
E:\testprjs\testit\DemoOfDatatStructures\DemoOfDatatStructures.cpp(79)
: warning C4786:
'std::reverse_bidirectional_iterator<std::_Tree<_SeatRowCols,std::pair<_SeatRowCols
const
::_Kfn,std::less<_SeatRowCols>,std::allocator<_PedData> >::iterator,std::pair<_SeatRowCols const ,_PedData>,std::pair<_SeatRowCols const ,_PedData> &,std::pair<_SeatRowCols const ,_PedData> *,int>' : identifier was truncated to
'255' characters in the debug information
E:\testprjs\testit\DemoOfDatatStructures\DemoOfDatatStructures.cpp(79)
: warning C4786:
'std::reverse_bidirectional_iterator<std::_Tree<_SeatRowCols,std::pair<_SeatRowCols
const
::_Kfn,std::less<_SeatRowCols>,std::allocator<_PedData> >::const_iterator,std::pair<_SeatRowCols const ,_PedData>,std::pair<_SeatRowCols const ,_PedData> const &,std::pair<_SeatRowCols const ,_PedData> const *,int>' : identifier
was truncated to '255' characters in the debug information
E:\testprjs\testit\DemoOfDatatStructures\DemoOfDatatStructures.cpp(79)
: warning C4786:
'std::pair<std::_Tree<_SeatRowCols,std::pair<_SeatRowCols const
::iterator,std::_Tree<_SeatRowCols,std::pair<_SeatRowCols const ,_PedData>,std::map<_SeatRowCols,_PedData,std::less<_SeatRowCols>,std::allocator<_PedData> >::_Kfn,std::less<_SeatRowCols>,std::alloc
ator<_PedData> >::iterator>' : identifier was truncated to '255'
characters in the debug information
E:\testprjs\testit\DemoOfDatatStructures\DemoOfDatatStructures.cpp(79)
: warning C4786:
'std::pair<std::_Tree<_SeatRowCols,std::pair<_SeatRowCols const
::const_iterator,std::_Tree<_SeatRowCols,std::pair<_SeatRowCols const ,_PedData>,std::map<_SeatRowCols,_PedData,std::less<_SeatRowCols>,std::allocator<_PedData> >::_Kfn,std::less<_SeatRowCols>,std:
:allocator<_PedData> >::const_iterator>' : identifier was truncated to
'255' characters in the debug information
e:\program files\microsoft visual studio\vc98\include\functional(86) :
error C2784: 'bool __cdecl std::eek:perator <(const class
std::multimap<_K,_Ty,_Pr,_A> &,const class std::multimap<_K,_Ty,_Pr,_A>
&)' : could not deduce template argument for 'const
class std::multimap<_K,_Ty,_Pr,_A> &' from 'const struct _SeatRowCols'
e:\program files\microsoft visual
studio\vc98\include\functional(86) : while compiling class-template
member function 'bool __thiscall std::less<struct
_SeatRowCols>::eek:perator ()(const struct _SeatRowCols &,const struct
_SeatRowCols &) const
'
e:\program files\microsoft visual studio\vc98\include\functional(86) :
error C2784: 'bool __cdecl std::eek:perator <(const class
std::map<_K,_Ty,_Pr,_A> &,const class std::map<_K,_Ty,_Pr,_A> &)' :
could not deduce template argument for 'const class std
::map<_K,_Ty,_Pr,_A> &' from 'const struct _SeatRowCols'
e:\program files\microsoft visual
studio\vc98\include\functional(86) : while compiling class-template
member function 'bool __thiscall std::less<struct
_SeatRowCols>::eek:perator ()(const struct _SeatRowCols &,const struct
_SeatRowCols &) const
'
e:\program files\microsoft visual studio\vc98\include\functional(86) :
error C2784: 'bool __cdecl std::eek:perator <(const class
std::_Tree<_K,_Ty,_Kfn,_Pr,_A> &,const class
std::_Tree<_K,_Ty,_Kfn,_Pr,_A> &)' : could not deduce template argument
for 'c
onst class std::_Tree<_K,_Ty,_Kfn,_Pr,_A> &' from 'const struct
_SeatRowCols'
e:\program files\microsoft visual
studio\vc98\include\functional(86) : while compiling class-template
member function 'bool __thiscall std::less<struct
_SeatRowCols>::eek:perator ()(const struct _SeatRowCols &,const struct
_SeatRowCols &) const
'
e:\program files\microsoft visual studio\vc98\include\functional(86) :
error C2784: 'bool __cdecl std::eek:perator <(const class
std::reverse_iterator<_RI,_Ty,_Rt,_Pt,_D> &,const class
std::reverse_iterator<_RI,_Ty,_Rt,_Pt,_D> &)' : could not deduce te
mplate argument for 'const class
std::reverse_iterator<_RI,_Ty,_Rt,_Pt,_D> &' from 'const struct
_SeatRowCols'
e:\program files\microsoft visual
studio\vc98\include\functional(86) : while compiling class-template
member function 'bool __thiscall std::less<struct
_SeatRowCols>::eek:perator ()(const struct _SeatRowCols &,const struct
_SeatRowCols &) const
'
e:\program files\microsoft visual studio\vc98\include\functional(86) :
error C2784: 'bool __cdecl std::eek:perator <(const struct
std::pair<_T1,_T2> &,const struct std::pair<_T1,_T2> &)' : could not
deduce template argument for 'const struct std::pair<
_T1,_T2> &' from 'const struct _SeatRowCols'
e:\program files\microsoft visual
studio\vc98\include\functional(86) : while compiling class-template
member function 'bool __thiscall std::less<struct
_SeatRowCols>::eek:perator ()(const struct _SeatRowCols &,const struct
_SeatRowCols &) const
'
e:\program files\microsoft visual studio\vc98\include\functional(86) :
error C2784: 'bool __cdecl operator <(_Interface *,class
_com_ptr_t<_InterfacePtr> &)' : could not deduce template argument for
' *' from 'const struct _SeatRowCols'
e:\program files\microsoft visual
studio\vc98\include\functional(86) : while compiling class-template
member function 'bool __thiscall std::less<struct
_SeatRowCols>::eek:perator ()(const struct _SeatRowCols &,const struct
_SeatRowCols &) const
'
e:\program files\microsoft visual studio\vc98\include\functional(86) :
error C2784: 'bool __cdecl operator <(int,class _com_ptr_t<_Interface>
&)' : could not deduce template argument for 'overloaded function type'
from 'overloaded function type'
e:\program files\microsoft visual
studio\vc98\include\functional(86) : while compiling class-template
member function 'bool __thiscall std::less<struct
_SeatRowCols>::eek:perator ()(const struct _SeatRowCols &,const struct
_SeatRowCols &) const
'
e:\program files\microsoft visual studio\vc98\include\functional(86) :
error C2676: binary '<' : 'const struct _SeatRowCols' does not define
this operator or a conversion to a type acceptable to the predefined
operator
e:\program files\microsoft visual
studio\vc98\include\functional(86) : while compiling class-template
member function 'bool __thiscall std::less<struct
_SeatRowCols>::eek:perator ()(const struct _SeatRowCols &,const struct
_SeatRowCols &) const
'
Error executing cl.exe.


Please gimme some suggestions.

Regards
kamaraj.M
 
E

Earl Purple

Hi
I am using the std:: map as following.

typedef struct _SeatRowCols
{
long nSeatRow;
unsigned char ucSeatLetter;
}SeatRowCols;

typedef struct _NetData
{
SeatRowCols tSeatRowCols;
unsigned char ucMacAddress[MAC_LENGTH];
unsigned char ucAdminStatus;
unsigned char ucLocalFault;

}NetData;

That is very much a "C" way of defining a struct. That's not to say
it's wrong, perhaps you
are writing a library that can be used for C as well as C++. If that is
not the case then perhaps
you should use C++ classes.
typedef std::map <SeatRowCols, PedData> MAP_PED_DATA;

I don't know what PedData is but in any case as std::map is a sorted
container it needs a means
by which to sort. You have 4 ways to achieve this:

1. Overload operator < for your struct SeatRowCols.
2. Specialise std::less for SeatRowCols.
3. Write your own comparison function or functor and pass it to
std::map as the 3rd parameter.
This last method is preferred if there's more than one way to sort a
SeatRowCols.
4 (not advised): Provide an operator overload for double() or long()
that returns a sortable value.
From the rest of the code it appears you are writing in C apart from
your use of std::map. Although
I agree you might want to provide a C interface to a library, I would
suggest that once you choose to
implement in C++, you use C++ all the way through the implementation
unless you reach a
performance-critical situation where profiling shows that the C
approach is faster (or if the C approach
is a lot clearer, which in your case it isn't most of the time).
 
K

kamaraj80

Sorry, a small correction, the structure name is not NetData, that is
PedData

typedef struct _PedData
{
SeatRowCols tSeatRowCols;
unsigned char ucMacAddress[MAC_LENGTH];
unsigned char ucAdminStatus;
unsigned char ucLocalFault;


}PedData
 
E

Earl Purple

Sorry, a small correction, the structure name is not NetData, that is
PedData

typedef struct _PedData
{
SeatRowCols tSeatRowCols;
unsigned char ucMacAddress[MAC_LENGTH];
unsigned char ucAdminStatus;
unsigned char ucLocalFault;


}PedData

and needs a semicolon terminator.

Doesn't change the answers in my previous post. By the way, I don't
know what MAC_LENGTH is but it's better if you avoid #defines and use
either enum or const size_t. If this isn't needed for C then it should
also be enclosed at either class or namespace scope.
 
B

Ben Pope

Sorry, a small correction, the structure name is not NetData, that is
PedData

typedef struct _PedData
{
SeatRowCols tSeatRowCols;
unsigned char ucMacAddress[MAC_LENGTH];
unsigned char ucAdminStatus;
unsigned char ucLocalFault;


}PedData

Prefer not to prefix identifiers with an underscore. Often the
identifier will be reserved for the implementation. Just stick the
underscore on the end, although that's often convention for private
member variables.

In this case, you don't even need to identify the struct, since you are
typedefing it:

typedef struct {
SeatRowCols tSeatRowCols;
unsigned char ucMacAddress[MAC_LENGTH];
unsigned char ucAdminStatus;
unsigned char ucLocalFault;
} PedData;

If this is only used in C++ code (and not C), you can prefer the following:

struct PedData {
SeatRowCols tSeatRowCols;
unsigned char ucMacAddress[MAC_LENGTH];
unsigned char ucAdminStatus;
unsigned char ucLocalFault;
};

Ben Pope
 
K

kamaraj80

I am using this structure inside a COM Component. So we can use C++
style coding, right?
 
P

pavel.turbin

to use map with non POD datatype you have to declare and implement the
operator less (<) for key type. POD types have this operator as
compiler built-in.

typedef struct _SeatRowCols
{
long nSeatRow;
unsigned char ucSeatLetter;


bool operator()(const _SeatRowCols &left, const _SeatRowCols
&right) const
{

// define your comparsion conditions for the "SeatRowCols"
// you can't write just "return false" as it'll lead only one item
in your "map" :)

}
}SeatRowCols;

typedef std::map <SeatRowCols, NetData> MAP_PED_DATA;

Might be it is good idea to use pointer or reference to "NetData *" or
"NetData &" to avoid extra copy of NetData. I usually use poiunters.

typedef std::map <SeatRowCols, NetData *> MAP_PED_DATA;

Regards, Pavel
 
P

pavel.turbin

to use map with non POD datatype you have to declare and implement the
operator less (<) for key type. POD types have this operator as
compiler built-in.

typedef struct _SeatRowCols
{
long nSeatRow;
unsigned char ucSeatLetter;


bool operator()(const _SeatRowCols &left, const _SeatRowCols
&right) const
{

// define your comparsion conditions for the "SeatRowCols"
// you can't write just "return false" as it'll lead only one item
in your "map" :)

}
}SeatRowCols;

typedef std::map <SeatRowCols, NetData> MAP_PED_DATA;

Might be it is good idea to use pointer or reference to "NetData *" or
"NetData &" to avoid extra copy of NetData. I usually use poiunters.

typedef std::map <SeatRowCols, NetData *> MAP_PED_DATA;

Regards, Pavel
 
K

kamaraj80

1. Overload operator < for your struct SeatRowCols

Thanx for the valuable suggestion, I get improved my code, now it is
working after overloading the operator <. But
Why we need to overload the < operator. Has it doing anything inside
the map?
Pl explain me.

kamaraj
 
B

Ben Pope

Thanx for the valuable suggestion, I get improved my code, now it is
working after overloading the operator <. But
Why we need to overload the < operator. Has it doing anything inside
the map?

You removed this part of the quotation:
"I don't know what PedData is but in any case as std::map is a sorted
container it needs a means by which to sort. You have 4 ways to achieve
this:"

So, I think the question was already answered.

Ben Pope
 
J

Jim Langston

Thanx for the valuable suggestion, I get improved my code, now it is
working after overloading the operator <. But
Why we need to overload the < operator. Has it doing anything inside
the map?
Pl explain me.

kamaraj

Maps are sorted containers. The map apparently uses less than < to sort.
So you need to override less than < so map knows how to sort it.

Consider, how do you sort two characters? Since char is a type of number
you use less than.
char1 < char2
How do you sort intergers/floats?
num1 < num2
How do you sort some class?
class1 < class2

so you need to have the less than overridden.
 
K

kamaraj80

Now it is working. For this I overload the < operator in SeatRowCols
structure.
Thanx Earl Purple, and Jim Langston for their valuable explaination
on need of overlaoding < operator in data structures while using them
as a mapkey. Thanx to all other contributors.

Kamaraj
 
E

Earl Purple

to use map with non POD datatype you have to declare and implement the
operator less (<) for key type. POD types have this operator as
compiler built-in.
No they don't. operator< is compiler-defined for primitive types only.
std::string also has operator< defined as part of the standard library.
bool operator()(const _SeatRowCols &left, const _SeatRowCols
&right) const
{

Wrong operator. You want to overload

bool operator<( ()(const _SeatRowCols &left, const _SeatRowCols
&right) const

as a non-member function (you made yours a member).

You can (less preferably) overload it as a member

bool SeatRowCols::eek:perator<( const SeatRowCols & rhs ) const;

noting that the function as well as the parameter should be const,.
 
E

Earl Purple

Jim said:
Maps are sorted containers. The map apparently uses less than < to sort.
So you need to override less than < so map knows how to sort it.

To be pedantic, they use std::less< T >() to sort unless an alternative
predicate is supplied. And std::less< T > uses operator< unless it is
specialised to do otherwise. Specialising the template to is therefore
one alternative although I wouldn't recommend it. (You'd expect
std::less to call operator< wouldn't you).
 

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

Members online

Forum statistics

Threads
473,968
Messages
2,570,153
Members
46,699
Latest member
AnneRosen

Latest Threads

Top