如何将 unordered_set::contains() 与自定义类一起使用?

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

我第一次使用

std::unordered_set
进行自定义类型,我不知道我缺少什么来为我的集编译
contains()

我基本上有一个看起来像这样的课程:

class MyClass
{
// Ctor/Dtor
public:
    MyClass(const std::string& name /* + other params in my real use case */) : m_name(name) {}
    ~MyClass() = default;

// Members
private:
    std::string m_name;

// Operators
public:
    // Equal operators
    bool operator==(const MyClass &other) const
    {
        return m_name == other.m_name;
    }

    bool operator==(const std::string& other) const
    {
        return m_name == other;
    }

    bool operator==(const char* other) const
    {
        return m_name == other;
    }

// Functors
public:
    // Hash functor
    struct Hash
    {
        std::size_t operator()(const MyClass &class_) const
        {
            return std::hash<std::string>()(class_.m_name);
        }

        std::size_t operator()(const std::string &name) const
        {
            return std::hash<std::string>()(name);
        }

        std::size_t operator()(const char* name) const 
        {
            return std::hash<std::string>()(name);
        }
    };

    // Equal functor
    struct Equal
    {
        bool operator()(const MyClass &lhs, const MyClass &rhs) const
        {
            return lhs.m_name == rhs.m_name;
        }

        bool operator()(const MyClass &lhs, const std::string &rhs) const
        {
            return lhs.m_name == rhs;
        }

        bool operator()(const std::string &lhs, const MyClass &rhs) const
        {
            return lhs == rhs.m_name;
        }

        bool operator()(const MyClass &lhs, const char* rhs) const
        {
            return lhs.m_name == rhs;
        }

        bool operator()(const char* lhs, const MyClass &rhs) const
        {
            return lhs == rhs.m_name;
        }
    };

};

使用这个类,我想创建一个

std::unordered_set
并检查名称为
key1
的元素是否存在。为此,我想使用以下代码:

int main()
{
    // I tried both, but none of them seem to work
    std::unordered_set<MyClass, MyClass::Hash, MyClass::Equal> set;
    // std::unordered_set<MyClass, MyClass::Hash> set;

    // Add sample elements to the set
    set.emplace("key1");
    set.emplace("key2");

    // Check if the set contains "key1"
    if (set.contains("key1")) // Compile error on this line. Why does this not work?
    {
        std::wcout << L"set contains key1." << std::endl;
    } else {
        std::wcout << L"set doesn't contain key1." << std::endl;
    }

    return 0;
}

但是我在调用

contains()
时不断收到编译器错误:

`错误:没有匹配的函数可用于调用“std::unordered_set::contains(const char [5])”[...]

我不明白为什么,也找不到任何相关资源。

我想我错过了一些东西,因为以下代码使用

std::string
确实可以正常工作:

int main()
{
    std::unordered_set<std::string> set;
   
    // Add sample elements to the set
    set.emplace("key1");
    set.emplace("key2");

    // Check if the set contains "key1"
    if (set.contains("key1")) // Why does this not work?
    {
        std::wcout << L"set contains key1." << std::endl;
    } else {
        std::wcout << L"set doesn't contain key1." << std::endl;
    }

    return 0;
}
c++ unordered-set
1个回答
4
投票

您的问题是

set.contains("key1")
传入的参数不是
MyClass
对象,仅当
Hash::is_transparent
KeyEqual::is_transparent
都有效且各自表示一种类型时才有效。这意味着您需要将
Hash
Equals
结构更改为以下内容:

struct Hash
{
    using is_transparent = std::true_type;
    
    std::size_t operator()(const MyClass &class_) const
    {
        return std::hash<std::string>()(class_.m_name);
    }

    std::size_t operator()(const std::string &name) const
    {
        return std::hash<std::string>()(name);
    }

    std::size_t operator()(const char* name) const 
    {
        return std::hash<std::string>()(name);
    }
};

// Equal functor
struct Equal
{
    using is_transparent = std::true_type;
    
    bool operator()(const MyClass &lhs, const MyClass &rhs) const
    {
        return lhs.m_name == rhs.m_name;
    }

    bool operator()(const MyClass &lhs, const std::string &rhs) const
    {
        return lhs.m_name == rhs;
    }

    bool operator()(const std::string &lhs, const MyClass &rhs) const
    {
        return lhs == rhs.m_name;
    }

    bool operator()(const MyClass &lhs, const char* rhs) const
    {
        return lhs.m_name == rhs;
    }

    bool operator()(const char* lhs, const MyClass &rhs) const
    {
        return lhs == rhs.m_name;
    }
};

现在将通知

std::unordered_set
,它可以将哈希器和比较器与密钥类型以外的对象一起使用。

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