找不到最新插入到std :: map中的密钥

问题描述 投票:3回答:1

我的问题是,无论我插入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;
    }
}

非常感谢,暗示可以解决问题所在。

c++ oop std stdmap
1个回答
8
投票

st::map中键的比较必须为严格,弱顺序,即必须遵守以下规则:

  1. (a < a) == false
  2. [(a < b) == true && (b < c) == true意味着(a < c) == true
  3. [(a < b) == true意味着(b < a) == false
  4. [(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);
}

此比较运算符实际上定义了一个更强的阶:总阶。

© www.soinside.com 2019 - 2024. All rights reserved.