【问题标题】:Find any element in a map by matching a sub-element of the key通过匹配键的子元素来查找地图中的任何元素
【发布时间】:2020-04-13 06:13:04
【问题描述】:

我有一个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-&gt;first.a == 1,但无论如何我可以使用map::count() 函数来获得它吗?

我在 CLI C++ 代码中使用它,所以我似乎无法使用 lambda 函数。

【问题讨论】:

  • 仅供参考,您的KeyClass 需要定义一个operator&lt; 才能用作std::map 键。

标签: c++ clr stdmap


【解决方案1】:

您可以使用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()) {
    ...
}

如果不能使用 lambda,您可以使用仿函数:

#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(),可以使用手动循环:

myMapType::iterator iter = mapVariable.begin();
while (iter != mapVariable.end()) {
    if (iter->first.a == 1) break;
    ++iter;
}
if (iter != mapVariable.end()) {
    ...
}

【讨论】:

    【解决方案2】:

    您可以将std::find_if 与 lambda 一起使用:

    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
    });
    

    或者不使用 lambda:

    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&amp; 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
        }
    

    【讨论】:

    • 除了 lambda 函数,我们还有什么可以使用的吗?当我在 CLI/C++ 代码中使用它时,它不允许我使用 lambda 函数
    • @Humble_Aspirant 我对 C++/CLI 知之甚少。恐怕它是一种与 C++ 不同的语言。如果您正在使用,您应该将问题的语言标签从 c++ 更改为 c++-cli
    • @Humble_Aspirant 一个 lambda 只是函子的语法糖 - 一个 class/struct 定义了一个 operator()。你可以手动定义一个仿函数
    猜你喜欢
    • 2012-12-02
    • 2020-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-01
    相关资源
    最近更新 更多