c++templatestemplate-specializationstdhash

How can I hash a type using the std::hash of its base class?


I have a class template C<B> which inherits from std::string, and I want to make it hashable like a normal std::string. I have written the following code, and it compiles.

I wonder if it is the correct implementation. Since a cast from derived class to base class may truncate memory, I wonder if it will cost too much?

#include <unordered_set>
#include <string>

template <bool B>
struct C : std::string
{
    C(std::string s) : std::string(s) {}
};

namespace std {

    template <bool B>
    struct hash<C<B>>
    {
        std::size_t operator()(const C<B> &k) const {
            return std::hash<std::string>()(static_cast<std::string>(k));
        }
    };

} // namespace std

int main() {
    std::unordered_set<C<false>> s;
    std::string c = C<false>("a");
    s.insert(c);
    return 0;
}

Solution

  • Yes, the implementation will work, but static_cast<std::string>(k) is not needed - and will create a temporary std::string which you probably would like to avoid.

    If you instead make it static_cast<const std::string&>(k), it will not create a temporary std::string. Same thing if you simply do:

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