【问题标题】:C++: Defining Hash Function for Nested Internal, Protected ClassC++:为嵌套的内部受保护类定义哈希函数
【发布时间】:2020-07-05 18:44:28
【问题描述】:

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

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

然而,这充满了编译器错误,包括“无效的友元声明”和“类“std::hash”的显式特化必须在其首次使用之前(在“C:\Program Files (x86)\ Microsoft Visual Studio\2017\Enterprise\VC\Tools\MSVC\14.16.27023\include\type_traits")"

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

【问题讨论】:

    标签: c++ oop hash unordered-map protected


    【解决方案1】:

    我想这就是你想要的:

    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

    【讨论】:

    • 抱歉,错过了将MyHash 传递给地图声明的重要环节。
    【解决方案2】:

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

    但是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;
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-08
      • 2018-04-24
      • 2022-11-16
      • 2011-01-02
      • 1970-01-01
      • 2011-03-22
      • 1970-01-01
      相关资源
      最近更新 更多