找不到最新插入 std::map 的密钥
The latest inserted key into std::map cannot be found
我的问题是,无论我插入 std::map
的最后一个元素如何,我都找不到它。
我有以下地图,它将 Color 作为键并将其编码为某种对象类型(枚举)。
class ColorEncoder {
private:
std::map<Color, Object::Type> validObjects;
public:
ColorEncoder() {
load(Color(76, 177, 34), Object::Player);
load(Color(36, 28, 237), Object::Block);
// load(Color(0, 111, 222), Object::PleaseDont); // uncomment this line and everything will work correctly,
// but the map will have one garbage value
}
void load(Color color, Object::Type type) {
validObjects.insert(std::make_pair(color, type));
}
auto& getValidObjects() {
return validObjects;
}
};
我还有 array
种颜色。目标是验证每个数组元素是否确实存在于映射中。
因此,我遍历数组,每次检查当前数组元素是否作为键存在于映射中:
class BMP_Analyzer {
public:
// assume data size is 12
BMP_Analyzer(std::unique_ptr<Color[]>& data, std::map<Color, Object::Type>& validObjects) {
for (int i = 0; i < 12; i++) {
if (validObjects.find(data[i]) == validObjects.end()) {
std::cout << "Not found in the map!\t";
std::cout << "Blue: " << (uint16_t) data[i].blue << " " << " Green: "
<< (uint16_t) data[i].green << " Red: " << (uint16_t) data[i].red
<< " is not mapped!" << std::endl;
}
}
}
};
示例输出:
Not found in the map! Blue: 36 Green: 28 Red: 237 is not mapped!
Not found in the map! Blue: 36 Green: 28 Red: 237 is not mapped!
但是,如果我取消注释:
// load(Color(0, 111, 222), Object::PleaseDont);
然后就会正确检测到上面以前没有找到的颜色:(36, 28, 237)
.
对我来说,这看起来像是一个错误之类的,但老实说,我不知道潜在的错误在哪里。
颜色定义如下,重载 operator<
因此它可以作为 std::map
的键。
struct Color {
uint8_t blue;
uint8_t green;
uint8_t red;
Color() = default;
Color(uint8_t blue, uint8_t green, uint8_t red)
:blue{blue},
green{green},
red{red}
{
}
bool operator<(const Color& other) const {
return blue != other.blue || green != other.green || red != other.red;
}
}
非常欢迎任何可能存在问题的提示,谢谢。
st::map
中键的比较必须是严格的弱顺序,即必须满足以下规则:
(a < a) == false
(a < b) == true && (b < c) == true
表示 (a < c) == true
(a < b) == true
表示 (b < a) == false
(a < b) == false && (b < a) == false) && (b < c) == false && (c < b) == false)
表示 (a < c) && (c < a) == false
对于结构来说,实现这一点的最简单方法是利用 std::tuple
比较:
bool operator< (Color const& c0, Color const& c1) {
return std::tie(c0.blue, c0.green, c0.red) < std::tie(c1.blue, c1.green, c1.red);
}
这个比较运算符实际上定义了一个更强的顺序:总顺序。
我的问题是,无论我插入 std::map
的最后一个元素如何,我都找不到它。
我有以下地图,它将 Color 作为键并将其编码为某种对象类型(枚举)。
class ColorEncoder {
private:
std::map<Color, Object::Type> validObjects;
public:
ColorEncoder() {
load(Color(76, 177, 34), Object::Player);
load(Color(36, 28, 237), Object::Block);
// load(Color(0, 111, 222), Object::PleaseDont); // uncomment this line and everything will work correctly,
// but the map will have one garbage value
}
void load(Color color, Object::Type type) {
validObjects.insert(std::make_pair(color, type));
}
auto& getValidObjects() {
return validObjects;
}
};
我还有 array
种颜色。目标是验证每个数组元素是否确实存在于映射中。
因此,我遍历数组,每次检查当前数组元素是否作为键存在于映射中:
class BMP_Analyzer {
public:
// assume data size is 12
BMP_Analyzer(std::unique_ptr<Color[]>& data, std::map<Color, Object::Type>& validObjects) {
for (int i = 0; i < 12; i++) {
if (validObjects.find(data[i]) == validObjects.end()) {
std::cout << "Not found in the map!\t";
std::cout << "Blue: " << (uint16_t) data[i].blue << " " << " Green: "
<< (uint16_t) data[i].green << " Red: " << (uint16_t) data[i].red
<< " is not mapped!" << std::endl;
}
}
}
};
示例输出:
Not found in the map! Blue: 36 Green: 28 Red: 237 is not mapped!
Not found in the map! Blue: 36 Green: 28 Red: 237 is not mapped!
但是,如果我取消注释:
// load(Color(0, 111, 222), Object::PleaseDont);
然后就会正确检测到上面以前没有找到的颜色:(36, 28, 237)
.
对我来说,这看起来像是一个错误之类的,但老实说,我不知道潜在的错误在哪里。
颜色定义如下,重载 operator<
因此它可以作为 std::map
的键。
struct Color {
uint8_t blue;
uint8_t green;
uint8_t red;
Color() = default;
Color(uint8_t blue, uint8_t green, uint8_t red)
:blue{blue},
green{green},
red{red}
{
}
bool operator<(const Color& other) const {
return blue != other.blue || green != other.green || red != other.red;
}
}
非常欢迎任何可能存在问题的提示,谢谢。
st::map
中键的比较必须是严格的弱顺序,即必须满足以下规则:
(a < a) == false
(a < b) == true && (b < c) == true
表示(a < c) == true
(a < b) == true
表示(b < a) == false
(a < b) == false && (b < a) == false) && (b < c) == false && (c < b) == false)
表示(a < c) && (c < a) == false
对于结构来说,实现这一点的最简单方法是利用 std::tuple
比较:
bool operator< (Color const& c0, Color const& c1) {
return std::tie(c0.blue, c0.green, c0.red) < std::tie(c1.blue, c1.green, c1.red);
}
这个比较运算符实际上定义了一个更强的顺序:总顺序。