Error C2784 with std map

本文解决了一个使用自定义类型作为map键值时遇到的编译错误问题,通过使用multimap并为自定义类型实现比较运算符解决了重复键值的问题。
Hello, I'm using a map with a custom type in my code, and I'm getting these errors:

d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/functional(139) : error C2784: 'bool std::operator <(const std::queue<_Ty,_Container> &,const std::queue<_Ty,_Container> &)' : could not deduce template argument for 'const std::queue<_Ty,_Container> &' from 'const theRock::IGameListener'
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/queue(97) : see declaration of 'std::operator`<'
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/functional(138) : while compiling class-template member function 'bool std::less<_Ty>::operator ()(const _Ty &,const _Ty &) const'
with
[
_Ty=theRock::IGameListener
]
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/map(67) : see reference to class template instantiation 'std::less<_Ty>' being compiled
with
[
_Ty=theRock::IGameListener
]
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/xtree(23) : see reference to class template instantiation 'std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,_Mfl>' being compiled
with
[
_Kty=theRock::IGameListener,
_Ty=theRock::IGameEvent::EventType,
_Pr=std::less<theRock::IGameListener>,
_Alloc=std::allocator<std::pair<const theRock::IGameListener,theRock::IGameEvent::EventType>>,
_Mfl=false
]
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/xtree(65) : see reference to class template instantiation 'std::_Tree_nod<_Traits>' being compiled
with
[
_Traits=std::_Tmap_traits<theRock::IGameListener,theRock::IGameEvent::EventType,std::less<theRock::IGameListener>,std::allocator<std::pair<const theRock::IGameListener,theRock::IGameEvent::EventType>>,false>
]
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/xtree(87) : see reference to class template instantiation 'std::_Tree_ptr<_Traits>' being compiled
with
[
_Traits=std::_Tmap_traits<theRock::IGameListener,theRock::IGameEvent::EventType,std::less<theRock::IGameListener>,std::allocator<std::pair<const theRock::IGameListener,theRock::IGameEvent::EventType>>,false>
]
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/xtree(105) : see reference to class template instantiation 'std::_Tree_val<_Traits>' being compiled
with
[
_Traits=std::_Tmap_traits<theRock::IGameListener,theRock::IGameEvent::EventType,std::less<theRock::IGameListener>,std::allocator<std::pair<const theRock::IGameListener,theRock::IGameEvent::EventType>>,false>
]
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/map(77) : see reference to class template instantiation 'std::_Tree<_Traits>' being compiled
with
[
_Traits=std::_Tmap_traits<theRock::IGameListener,theRock::IGameEvent::EventType,std::less<theRock::IGameListener>,std::allocator<std::pair<const theRock::IGameListener,theRock::IGameEvent::EventType>>,false>
]
c:/theRock/bumblebee/Source/include/IGameManager.h(85) : see reference to class template instantiation 'std::map<_Kty,_Ty>' being compiled
with
[
_Kty=theRock::IGameListener,
_Ty=theRock::IGameEvent::EventType
]
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/functional(139) : error C2784: 'bool std::operator <(const std::deque<_Ty,_Alloc> &,const std::deque<_Ty,_Alloc> &)' : could not deduce template argument for 'const std::deque<_Ty,_Ax> &' from 'const theRock::IGameListener'
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/deque(999) : see declaration of 'std::operator`<'
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/functional(139) : error C2784: 'bool std::operator <(const std::list<_Ty,_Alloc> &,const std::list<_Ty,_Alloc> &)' : could not deduce template argument for 'const std::list<_Ty,_Ax> &' from 'const theRock::IGameListener'
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/list(991) : see declaration of 'std::operator`<'
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/functional(139) : error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Ax> &' from 'const theRock::IGameListener'
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/string(148) : see declaration of 'std::operator`<'
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/functional(139) : error C2784: 'bool std::operator <(const _Elem *,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const T1 *' from 'const theRock::IGameListener'
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/string(138) : see declaration of 'std::operator`<'
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/functional(139) : error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Ax> &' from 'const theRock::IGameListener'
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/string(128) : see declaration of 'std::operator`<'
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/functional(139) : error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const theRock::IGameListener'
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/xtree(1170) : see declaration of 'std::operator`<'
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/functional(139) : error C2784: 'bool std::operator <(const std::vector<_Ty,_Alloc> &,const std::vector<_Ty,_Alloc> &)' : could not deduce template argument for 'const std::vector<_Ty,_Ax> &' from 'const theRock::IGameListener'
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/vector(915) : see declaration of 'std::operator`<'
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/functional(139) : error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'const theRock::IGameListener'
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/xutility(655) : see declaration of 'std::operator`<'
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/functional(139) : error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'const theRock::IGameListener'
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/utility(73) : see declaration of 'std::operator`<'
d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/functional(139) : error C2676: binary '<' : 'const theRock::IGameListener' does not define this operator or a conversion to a type acceptable to the predefined operator



This is the typedef:

typedef map<IGameListener, typename theRock::IGameEvent::EventType> ListenerMap;

and this is the code:

ListenerMap::iterator it = mListeners.begin();
ListenerMap::iterator itEnd = mListeners.end();
while(it != itEnd)
{
theRock::IGameListener tempListener = it->first;
if( tempListener.getName().compare(gameListener.getName()))
//Listener exists, or listener with same name exists
return false;
it++;
}
mListeners.insert(ListenerMap::value_type(gameListener, eventType));

The error goes away once I comment out the mListeners.insert line, and I can't figure out what I'm doing wrong here. Any help is appreciated.



 User Rating: 1020   |  Rate This User Send Private MessageView ProfileReport this Post to a Moderator | Link

typedef map<IGameListener, typename theRock::IGameEvent::EventType> ListenerMap;


The first template parameter to std::map is the key type and the second is the type to store in the map. From your typedef it looks like you have these backward. Instead try:

typedef map< typename theRock::IGameEvent::EventType, IGameListener> ListenerMap;


 User Rating: 1114   |  Rate This User Send Private MessageView ProfileReport this Post to a Moderator | Link

Well, the reason I did it this way is because I'm trying to associate a listener with an event type. Correct me if I'm wrong but I don't think that I can have multiple entries in a map with the same key... If that is true then I can't use the event type as the key because there will be multiple listeners that may need to be associated with the same type of event. I did notice that its complaining about not having a < operator defined in my game listener class. I tried this:

bool operator < (const IGameListener &rhs)
{
Ogre::String lhs = rhs.getName();
if(lhs.compare(mName) >=1 )
return true;
else
return false;
}

but then I get this error:

d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/functional(139): error C2678: binary '<' : no operator found which takes a left-hand operand of type 'const theRock::IGameListener' (or there is no acceptable conversion)

and I'm not sure hot to fix that one...

 User Rating: 1020   |  Rate This User Send Private MessageView ProfileReport this Post to a Moderator | Link

ok, well I realized after writing that that I can use multimaps for duplicate keys. I guess my big question here is if I switch those around and use a multimap, is that going to fix my problem?

 User Rating: 1020   |  Rate This User Send Private MessageView ProfileReport this Post to a Moderator | Link

Quote:
Original post by Nox587
Correct me if I'm wrong but I don't think that I can have multiple entries in a map with the same key...


std::multimap



 User Rating: 1032   |  Rate This User Send Private MessageView ProfileReport this Post to a Moderator | Link

haha, beat you to the punch, but thank you for the help, and this did fix my problem.

 User Rating: 1020   |  Rate This User Send Private MessageView ProfileReport this Post to a Moderator | Link

Quote:
Original post by Nox587
Well, the reason I did it this way is because I'm trying to associate a listener with an event type. Correct me if I'm wrong but I don't think that I can have multiple entries in a map with the same key... If that is true then I can't use the event type as the key because there will be multiple listeners that may need to be associated with the same type of event. I did notice that its complaining about not having a < operator defined in my game listener class. I tried this:

bool operator < (const IGameListener &rhs)
{
Ogre::String lhs = rhs.getName();
if(lhs.compare(mName) >=1 )
return true;
else
return false;
}

but then I get this error:

d:/Program Files/Microsoft Visual Studio .NET 2003/Vc7/include/functional(139): error C2678: binary '<' : no operator found which takes a left-hand operand of type 'const theRock::IGameListener' (or there is no acceptable conversion)

and I'm not sure hot to fix that one...


Simple: In the map code, in order to build the structure, it will do comparisions of keys with the operator<. Since there's no free-function version, it will use the member function you provided, with the this-object being the one of the left-hand side. You need to mark the function such that the compiler knows that this object will not be modified (in addition to the right-hand side object, i.e. the parameter, not being modified):

bool operator< (const IGameListener &rhs) const




As a general rule, if you post in For Beginners and your code contains the word 'char', you have a bug. std::string roxors teh big one one one one.
"OMG! I'm so happy! I have "1 Friends"!!!" -- coldacid
"Basically whenever you invoke the dread ellipses construct you leave the happy world of type safety." -- SiCrane
"I mean, if you had sex for every time O'Reilly used the word Patriotism you'd be almost as awesome as Chuck Norris." -- tthibault

<triforce101> uh im not a noob i finished the game

 User Rating: 1990   |  Rate This User Send Private MessageView ProfileReport this Post to a Moderator | Link

As has been pointed out, you're getting those errors is a result of there being no operator<() overload for the type IGameListener. Assuming EventType is a built-in type used for enumeration (enums are just ints) then it'll already have a built-in less-than comparison so using std::multimap will be fine.




"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V

 User Rating: 1639   |  Rate This User Send Private MessageView ProfileView JournalReport this Post to a Moderator | Link

 

(摘自:http://www.gamedev.net/community/forums/topic.asp?topic_id=363456)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值