我有一个
std::map<a,std::vector<b>> m;
a是结构
struct a
{
std::string c,d;
bool operator<(const a &o)
{ return !(c==o.c && d==o.d);}
}
我以这种方式填充地图
for(/*blah blah*/)
{
m[A].push_back(B)
}
在填充后我正在打印一些东西
std::cout << "Size:" << m.size() << std::endl;
int i=0;
for(std::map<a,std::vector<b>>::iterator it = m.begin(); it != m.end();i++,it++)
{
std::cout << "[" <<i <<"] " << it->second.size() << std::endl;
}
我得到的输出是
Size: 12
[0] 1
[1] 3
有人可以解释为什么map :: size()在迭代2个元素时显示12?
答案 0 :(得分:3)
将比较功能更改为
bool operator<(const a &o) const
{
if ( c == o.c )
return d < o.d;
return c < o.c;
}
请注意,将其作为非成员函数通常更有用。
您的比较功能必须遵循以下规则:
如果我们将
equiv(a, b)
定义为!comp(a, b) && !comp(b, a)
,那么要求就是comp 和等同都是传递关系:-
comp(a, b) && comp(b, c)
隐含comp(a, c)
-
equiv(a, b) && equiv(b, c)
隐含equiv(a, c)
地图使用比较函数生成数据结构并迭代它,所以如果你的函数错误,那么任何事情都可能发生。
答案 1 :(得分:2)
出于好奇,我在VS2010中尝试了这段代码。它不会编译。
bool operator<(const a &o) { return !(c==o.c && d==o.d); }
错误如下。
错误C2678:二进制'&lt;' :没有找到哪个运算符带有'const StdMapTest :: Exec :: a'类型的左手操作数(或者没有可接受的转换)
bool operator<(const a &o) const { return !(c==o.c && d==o.d); }
以上一行编译,但抛出一个断言:
表达式:无效的运算符&lt;
最后我试了这个。
bool operator<(const a &o) const { return (c == o.c) ? d < o.d : c < o.c; }
编译并且似乎正常工作。
我认为可以公平地说,一个足够好的编译器会使这个问题变得不必要。我确信VS2010不是唯一可以进行此类诊断的人。