我正在尝试使用自定义比较器构建一个地图,但是,我无法弄明白的东西出错了,无法将项目添加到地图中(具体来说,只能添加第一个项目)
struct byKey
{
bool operator () ( const Key &key1, const Key &key2) const {
return key1.keytoInt() < key2.keytoInt();
}
};
其中Key类有一个私有char [5],比如
char[0]=1, char[1]=2, char[3]=13, char[4]=20, char[5]=28
有一个匹配的去确保char数字[5]中的所有字符(小于32)并且可以转换为字符。如char = 0,它将搜索表,找到一个字符像A
我使用Key中的方法将其转换为int,然后与int进行比较
int Key :: keytoInt() const{
int sum;
sum=atoi(digit);
return sum;
}
我构建了一个带有键和值的地图表作为Key类型,但是,在尝试测试它时,我无法向表中添加项目,我不确定哪里出错。
没有编译错误,但是,从逻辑上讲,即使我已经三次插入地图,map.size()显示只有一个
map<Key,Key,byKey> firstmap;
map<Key,Key>::iterator it;
firstmap.insert(pair<Key,Key>(base,stepguess));
firstmap.insert(pair<Key,Key>(stepguess,base));
firstmap[stepguess]=base;
cout << "wait";
cout << "mymap.size() is " << firstmap.size() << '\n';
答案 0 :(得分:2)
每当你将你的密钥转换为整数来进行比较时,你最好直接比较这些字段。在这种特殊情况下,请考虑使用memcmp
,例如:
bool operator()(const Key& lhs, const Key& rhs) {
return memcmp(lhs.digit, rhs.digit, sizeof(Key::digit)) < 0;
}
在这种情况下, atoi
将始终返回0,除非您的值是有效的ASCII数字(这些数字不是这些数字)。
答案 1 :(得分:1)
所以,这就是我所知道的:
class Key {
public:
int keyToInt() const {
return atoi(digit);
}
private:
char digit[5];
};
您还建议,有一个示例Key
具有:
Key k;
k.digit = {1, 2, 13, 20, 28};
在这种情况下,您有2个错误:
digit
未终止。所以在其上调用atoi()
是未定义的行为。digit
中的ascii字符不是数字,因此您将获得无用的结果。我们还可以构建一个完整的测试用例,表明std::map
是理智的。
#include <map>
#include <cassert>
#include <cstring>
class Key {
public:
Key() {
strncpy(m_digit, "0", 5);
assert(m_digit[4] == '\0');
}
Key(const char *digit) {
strncpy(m_digit, digit, 5);
assert(m_digit[4] == '\0');
}
int keyToInt() const {
return atoi(m_digit);
}
private:
char m_digit[5];
};
struct byKey {
bool operator () ( Key const & key1, Key const & key2) const {
return key1.keyToInt() < key2.keyToInt();
}
};
int main() {
std::map<Key, Key, byKey> myMap;
Key a("123");
Key b("234");
myMap[a] = b;
myMap[b] = a;
assert(myMap.size() == 2);
}