0

I currently have a user defined class called ResultTableEntry and I would like to be able to create an std::unordered_set. I found out that would have a create a hash function for my class in order for me to initialise the set.

#include <vector>
#include <string>

class ResultTableEntry {
private:
    int relIndex;
    std::vector<int> paramIndex;
    std::vector<std::string> result;

public:
    ResultTableEntry::ResultTableEntry(int, std::vector<int>, std::vector<std::string>);

    int getRelationshipIndex();
    std::vector<int> getParameterIndex();
    std::vector<std::string> getResult();
};

namespace std {

    template <>
    struct hash<ResultTableEntry>
    {
        std::size_t operator()(const ResultTableEntry& k) const
        {

            size_t res = 17;
            for (auto p : k.getParameterIndex()) {
                res = res * 31 + hash<int>()(p);
            }
            for (auto r : k.getResult()) {
                res = res * 31 + hash<std::string>()(r);
            }
            res = res * 31 + hash<int>()(k.getRelationshipIndex());
            return res;
        }
    };
}

I implemented my hash function according to: C++ unordered_map using a custom class type as the key

However, I kept facing these errors.

  • the object has type qualifiers that are not compatible with the member function "ResultTableEntry::getParameterIndex"
  • the object has type qualifiers that are not compatible with the member function "ResultTableEntry::getResult"
  • the object has type qualifiers that are not compatible with the member function "ResultTableEntry::getRelationshipIndex"
  • expression having type 'const std::hash' would lose some const-volatile qualifiers in order to call 'size_t std::hash::operator ()(ResultTableEntry &)'

Removing 'const' in the parameter doesn't seem to help too. Is there something wrong with my implementation? I won't be able to use other library like boost.

1 Answer 1

0

You need to assure the compiler that the member functions will not modify the *this pointer

#include <vector>
#include <string>

class ResultTableEntry {
private:
    int relIndex;
    std::vector<int> paramIndex;
    std::vector<std::string> result;

public:
    ResultTableEntry(int, std::vector<int>, std::vector<std::string>);

    int getRelationshipIndex() const;
    std::vector<int> getParameterIndex() const;
    std::vector<std::string> getResult() const;
};

namespace std {

    template <>
    struct hash<ResultTableEntry>
    {
        std::size_t operator()(const ResultTableEntry& k) const
        {
            size_t res = 17;
            for (auto p : k.getParameterIndex()) {
                res = res * 31 + hash<int>()(p);
            }
            for (auto r : k.getResult()) {
                res = res * 31 + hash<std::string>()(r);
            }
            res = res * 31 + hash<int>()(k.getRelationshipIndex());
            return res;
        }
    };
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.