Найти любой элемент на карте, сопоставив подэлемент ключа - PullRequest
0 голосов
/ 13 апреля 2020

У меня есть std::map, ключ которого - другой класс. Как в примере ниже:

class KeyClass
{
public:
  int a;
  int b;
};

main(){
    //some code
    std::map<KeyClass, SomeOtherClass> mapVariable;
    KeyClass k1(); k1.a = 1; k1.b = 1;
    KeyClass k2(); k2.a = 2; k2.b = 2;
    mapVariable[k1] = SomeOtherClass();
    mapVariable[k2] = SomeOtherClass();

    //I am trying something like see if any element is there whose key.a = 1 (or may be key.a = 6 --> will fail here)?
}

Я попытался выполнить цикл по mapVariable и проверить iter->first.a == 1, но есть ли возможность использовать функцию map::count(), чтобы получить это?

I Я использую это в коде CLI C ++, поэтому кажется, что я не могу использовать лямбда-функцию.

Ответы [ 2 ]

0 голосов
/ 13 апреля 2020

Вы можете использовать std::find_if() для поиска по карте с помощью пользовательского предиката, например:

#include <algorithm>

using myMapType = std::map<KeyClass, SomeOtherClass>;
myMapType mapVariable;
...
auto iter = std::find_if(
    mapVariable.begin(), mapVariable.end(),
    [](const myMapType::value_type &entry){ return entry.first.a == 1; }
);
if (iter != mapVariable.end()) {
    ...
}

Если использование лямбда-выражения не является опцией, вы можете использовать вместо этого функтор :

#include <algorithm>

typedef std::map<KeyClass, SomeOtherClass> myMapType;

struct findKey
{
    bool operator()(const myMapType::value_type &entry) const { return entry.first.a == 1; }
};

myMapType mapVariable;
...
myMapType::iterator iter = std::find_if(mapVariable.begin(), mapVariable.end(), findKey());
if (iter != mapVariable.end()) {
    ...
}

Если вы не хотите использовать std::find_if(), вы можете использовать руководство l oop:

myMapType::iterator iter = mapVariable.begin();
while (iter != mapVariable.end()) {
    if (iter->first.a == 1) break;
    ++iter;
}
if (iter != mapVariable.end()) {
    ...
}
0 голосов
/ 13 апреля 2020

Вы можете использовать std::find_if с лямбда-выражением:

auto it = std::find_if(mapVariable.begin(), mapVariable.end(), [](const auto& pair) {
    return pair.first.a == 1; // first is the key, second is the value
});

Или без использования лямбда-выражения:

struct Functor {
    bool operator()(const decltype(mapVariable)::value_type& pair) const {
        return pair.first.a == 1;
    }
};

auto it = std::find_if(mapVariable.begin(), mapVariable.end(), Functor{});

Затем проверьте, есть ли совпадение :

if(it != mapVariable.end()) {
    // match found
}

Чтобы использовать перегрузку size_type std::map::count( const K& x ) const, функция сравнения, используемая на карте, должна быть прозрачной.

Пример:

struct Compare {
    using is_transparent = int;

    bool operator()(int x, const KeyClass& b) const {
        return x < b.a;
    }
    bool operator()(const KeyClass& a, int x) const {
        return a.a < x;
    }
    bool operator()(const KeyClass& a, const KeyClass& b) const {
        return a.a < b.a;
    }
};

//...
    std::map<KeyClass, SomeOtherClass, Compare> mapVariable;
    //...
    if(mapVariable.count(1)) {
        // match found
    }
...