C ++: определение функции Ha sh для вложенного внутреннего защищенного класса - PullRequest
0 голосов
/ 25 марта 2020

Я пытаюсь написать функцию ha sh для внутреннего класса, который является защищенным членом более крупного класса. Кроме того, функция ha sh должна использовать защищенные члены внутреннего класса (в данном случае, строку). Вот как это выглядит без функции ha sh:

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

Поскольку я использую InternalClass в качестве ключа в unordered_map в MasterClass, мне нужно определить функцию ha sh.

Я использую следующие ссылки:

Но я над головой. Моя лучшая догадка примерно такая:

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 :: ha sh »должна предшествовать его первое использование (в строке 719 "C: \ Program Files (x86) \ Microsoft Visual Studio \ 2017 \ Enterprise \ VC \ Tools \ MSVC \ 14.16.27023 \ include \ type_traits") "

Как я могу определить свою функцию ha sh для защищенного внутреннего класса (используя защищенные члены внутреннего класса)?

Ответы [ 2 ]

1 голос
/ 25 марта 2020

Я думаю, это то, что вы хотите:

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

Я бы также спросил, почему protected? protected делает элементы доступными для производных классов. Вы могли бы вырезать их в упрощении, но если вы не хотите использовать private.

0 голосов
/ 25 марта 2020

Я не думаю, что есть какой-либо способ достичь этого с помощью std::hash, потому что вам нужно определить специализацию std::hash, прежде чем вы определите MasterClass (потому что это должно быть в области пространства имен и потому что создание экземпляра типа m_Example_Map этого требует), и вам необходимо определить MasterClass перед тем, как определить специализацию, потому что ему нужен внутренний тип класса.

Но std::unordered_map не нужно использовать std::hash , Вместо этого вы можете указать свой собственный функтор ha sh:

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