C++:为嵌套内部定义哈希函数,受保护 Class

C++: Defining Hash Function for Nested Internal, Protected Class

我正在尝试为内部 class 编写哈希函数,它是更大 class 的受保护成员。此外,哈希函数应该使用内部 class 的受保护成员(在本例中为字符串)。所以这是没有哈希函数的样子:

class MasterClass
{
    public:
    // Blah blah blah
    protected:

        class InternalClass
        {
            public:
            // Blah blah blah 2
            protected:
                string m_Value;
        };

        unordered_map<InternalClass, uint> m_Example_Map;
};

因为我在 MasterClass 中的 unordered_map 中使用 InternalClass 作为键,所以我需要定义散列函数。

我正在使用以下参考资料:

但是我有点头疼了。我最好的猜测是这样的:

class MasterClass::InternalClass;
namespace std
{
    template<> struct hash<MasterClass::InternalClass>
    {
    public:
        size_t operator()(const MasterClass::InternalClass& i_Internal) const;
    };
}

class MasterClass
{
    public:
    // Blah blah blah
    protected:

        class InternalClass
        {
            public:
            // Blah blah blah 2
            protected:
                string m_Value;
        };

        unordered_map<InternalClass, uint> m_Example_Map;

        friend struct std::hash<MasterClass::InternalClass>::operator()(const MasterClass::InternalClass& i_Name) const;
};

namespace std
{
    template<> size_t hash<MasterClass::InternalClass>::operator()(const MasterClass::InternalClass& i_Internal) const
    {
        return(std::hash<std::string>{}(*i_Internal.m_Value);
    }
}

然而,这充满了编译器错误,包括 "Invalid friend declaration" 和 "explicit specialization of class "std::hash" must before its first use (at line 719 of "C:\Program Files (x86)\Microsoft Visual Studio17\Enterprise\VC\Tools\MSVC.16.27023\include\type_traits")"

如何为受保护的内部 class 定义哈希函数(使用内部 class 的受保护成员)?

我想这就是你想要的:

class MasterClass
{
public:
    // Blah blah blah
protected:

    class InternalClass; // Forward declaration needed for friend declaration

    class MyHash
    {
    public:
        size_t operator()(const MasterClass::InternalClass& i_Internal) const;
    };

    class InternalClass
    {
    public:
        // Blah blah blah 2
    protected:
        std::string m_Value;

        friend size_t MasterClass::MyHash::operator()(const MasterClass::InternalClass& i_Internal) const; // firend to allow access to m_value
    };

    std::unordered_map<InternalClass, unsigned, MyHash> m_Example_Map;
};

// Implementation of hash
size_t MasterClass::MyHash::operator()(const MasterClass::InternalClass& i_Internal) const
{
    return std::hash<std::string>{}(i_Internal.m_Value);
}

我也想问,为什么 protectedprotected 使派生 类 可以访问项目。您可能已经在简化中删除了这些,但如果不是,您想要使用 private.

我认为 std::hash 没有任何方法可以实现这一点,因为您需要在定义 MasterClass 之前定义 std::hash 的特化(因为它需要在命名空间范围内并且因为 m_Example_Map 类型的实例化需要它)并且您需要在定义特化之前定义 MasterClass 因为它需要内部 class 类型。

但是std::unordered_map不需要使用std::hash。您可以提供自己的哈希仿函数:

class MasterClass
{
    public:
    // Blah blah blah
    protected:

        class InternalClass
        {
            public:
                // Blah blah blah 2
                struct hash {
                    auto operator()(const InternalClass& v) const {
                        return std::hash<std::string>{}(v.m_Value);
                    }
                };
                bool operator==(const InternalClass& other) const {
                    return m_Value == other.m_Value;
                }
            protected:
                string m_Value;
        };

        unordered_map<InternalClass, uint, InternalClass::hash> m_Example_Map;
};