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