英文:
How can I hash a type using the std::hash of its base class?
问题
以下是翻译好的代码部分:
#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;
}
英文:
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;
}
答案1
得分: 6
是的,这个实现会工作,但不需要static_cast<std::string>(k)
- 并且会创建一个临时的std::string
,你可能想避免这种情况。
如果你改为static_cast<const std::string&&>(k)
,它就不会创建临时的std::string
。如果你只是这样做也一样:
std::size_t operator()(const C<B>& k) const {
return std::hash<std::string>()(k);
}
英文:
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);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论