[英]Invalid use of incomplete type struct std::hash with unordered_map with std::pair of enum class as key
I want to use a unordered_map<std::pair<enum_class,other_enum_class>,std::uint8_t>
for managing some pixelmap formats. 我想使用
unordered_map<std::pair<enum_class,other_enum_class>,std::uint8_t>
来管理一些像素图格式。
Here the minimal code : 这里的最小代码:
#include <unordered_map>
#include <utility>
#include <cstdint>
#include <iostream>
#include <functional>
enum class PNM : std::uint8_t { PBM, PGM, PPM };
enum class Format : bool { BIN, ASCII };
struct pair_hash {
public:
template <typename T, typename U>
std::size_t operator()(const std::pair<T, U> &x) const {
return std::hash<T>()(x.first) ^ std::hash<U>()(x.second);
}
};
int main(){
std::unordered_map<std::pair<PNM, Format>, std::uint8_t, pair_hash> k_magic_number ({
{ { PNM::PBM, Format::BIN }, 1 }, { { PNM::PGM, Format::BIN }, 2 }, { { PNM::PPM, Format::BIN }, 3 },
{ { PNM::PBM, Format::ASCII }, 4 }, { { PNM::PGM, Format::ASCII }, 5 }, { { PNM::PPM, Format::ASCII }, 6 }
});
std::cout << k_magic_number[std::make_pair<PNM, Format>(PNM::PBM, Format::BIN)];
}
With GCC I have an error when I try to instantiate the class : 使用GCC,当我尝试实例化类时出错 :
main.cpp:14:24: error: invalid use of incomplete type 'struct std::hash'
main.cpp:14:24:错误:无效使用不完整类型'struct std :: hash'
return std::hash()(x.first) ^ std::hash()(x.second);return std :: hash()(x.first)^ std :: hash()(x.second);
In file included from在包含的文件中
/usr/local/include/c++/5.2.0/bits/basic_string.h:5469:0,/usr/local/include/c++/5.2.0/bits/basic_string.h:5469:0,
from /usr/local/include/c++/5.2.0/string:52,来自/usr/local/include/c++/5.2.0/string:52,
[...][...]
With Clang I also have an error : 有了Clang,我也有一个错误 :
error: implicit instantiation of undefined template 'std::hash' return std::hash()(x.first) ^ std::hash()(x.second);
错误:未定义模板'std :: hash'的隐式实例化返回std :: hash()(x.first)^ std :: hash()(x.second); /usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.2.0/../../../../include/c++/5.2.0/bits/hashtable_policy.h:1257:16: note: in instantiation of function template specialization 'pair_hash::operator()' requested here [...]
/usr/local/bin/../lib/gcc/x86_64-unknown-linux-gnu/5.2.0/../../../../include/c++/5.2.0/bits/hashtable_policy。 h:1257:16:注意:在这里请求的函数模板特化'pair_hash :: operator()'实例化[...]
With VS2013 I have no error and the code compile and executes. 使用VS2013我没有错误,代码编译和执行。
What is missing in my code ? 我的代码中缺少什么?
g++-5 gives following errors: g ++ - 5给出以下错误:
invalid use of incomplete type
struct std::hash<PNM>
无效使用不完整类型
struct std::hash<PNM>
invalid use of incomplete type
struct std::hash<Format>
无效使用不完整类型
struct std::hash<Format>
So, you should just specialize std::hash
for PNM
and Format
. 所以,你应该专门为
PNM
和Format
std::hash
。
namespace std {
template<>
struct hash<PNM>
{
typedef PNR argument_type;
typedef size_t result_type;
result_type operator () (const argument_type& x) const
{
using type = typename std::underlying_type<argument_type>::type;
return std::hash<type>()(static_cast<type>(x));
}
};
template<>
struct hash<Format>
{
typedef Format argument_type;
typedef size_t result_type;
result_type operator () (const argument_type& x) const
{
using type = typename std::underlying_type<argument_type>::type;
return std::hash<type>()(static_cast<type>(x));
}
};
}
Or you can write template struct, that will works only for enums
with use of SFINAE (not sure, that it's not UB by standard, since it's not specialization actually). 或者你可以编写模板结构,它只适用于使用SFINAE的
enums
(不确定,它不是标准的UB,因为它实际上不是专业化)。
namespace std
{
template<typename E>
struct hash
{
typedef E argument_type;
typedef size_t result_type;
using sfinae = typename std::enable_if<std::is_enum<E>::value>::type;
result_type operator() (const E& e) const
{
using base_t = typename std::underlying_type<E>::type;
return std::hash<base_t>()(static_cast<base_t>(e));
}
};
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.