열거 형 클래스를 무순 맵 키로 사용할 수 없습니다.
열거 형 클래스를 포함하는 클래스가 있습니다.
class Shader {
public:
enum class Type {
Vertex = GL_VERTEX_SHADER,
Geometry = GL_GEOMETRY_SHADER,
Fragment = GL_FRAGMENT_SHADER
};
//...
그런 다음 다른 클래스에서 다음 코드를 구현하면 ...
std::unordered_map<Shader::Type, Shader> shaders;
... 컴파일 오류가 발생합니다.
...usr/lib/c++/v1/type_traits:770:38:
Implicit instantiation of undefined template 'std::__1::hash<Shader::Type>'
여기서 오류의 원인은 무엇입니까?
나는 functor 객체를 사용하여 다음의 해시를 계산합니다 enum class
.
struct EnumClassHash
{
template <typename T>
std::size_t operator()(T t) const
{
return static_cast<std::size_t>(t);
}
};
이제 다음의 세 번째 템플릿 매개 변수로 사용할 수 있습니다 std::unordered_map
.
enum class MyEnum {};
std::unordered_map<MyEnum, int, EnumClassHash> myMap;
따라서의 전문화를 제공 할 필요가 없으며 std::hash
템플릿 인수 추론이 작업을 수행합니다. 또한 단어 를 사용 하고 유형 에 따라 사용 하거나 using
직접 만들 수 있습니다 .unordered_map
std::hash
EnumClassHash
Key
template <typename Key>
using HashType = typename std::conditional<std::is_enum<Key>::value, EnumClassHash, std::hash<Key>>::type;
template <typename Key, typename T>
using MyUnorderedMap = std::unordered_map<Key, T, HashType<Key>>;
이제 MyUnorderedMap
with enum class
또는 다른 유형을 사용할 수 있습니다 .
MyUnorderedMap<int, int> myMap2;
MyUnorderedMap<MyEnum, int> myMap3;
이론적으로 HashType
사용할 수 있습니다 std::underlying_type
다음은 EnumClassHash
필요하지 않습니다. 이와 같은 것일 수 있지만 아직 시도하지 않았습니다 .
template <typename Key>
using HashType = typename std::conditional<std::is_enum<Key>::value, std::hash<std::underlying_type<Key>::type>, std::hash<Key>>::type;
std::underlying_type
작품을 사용한다면 표준에 대한 아주 좋은 제안이 될 수 있습니다.
이것은 표준의 결함으로 간주되었으며 C ++ 14에서 수정되었습니다 : http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2148
이는 6.1부터 gcc와 함께 제공되는 libstdc ++ 버전에서 수정되었습니다 : https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60970 .
2013 년 clang의 libc ++에서 수정되었습니다 : http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20130902/087778.html
매우 간단한 해결책은 다음과 같은 해시 함수 객체를 제공하는 것입니다.
std::unordered_map<Shader::Type, Shader, std::hash<int> > shaders;
이것은 열거 형 키를위한 것이므로 std :: hash의 전문화를 제공 할 필요가 없습니다.
KerrekSB가 지적했듯이을 std::hash
사용하려면 std::unordered_map
다음과 같은 전문화를 제공해야합니다 .
namespace std
{
template<>
struct hash< ::Shader::Type >
{
typedef ::Shader::Type argument_type;
typedef std::underlying_type< argument_type >::type underlying_type;
typedef std::hash< underlying_type >::result_type result_type;
result_type operator()( const argument_type& arg ) const
{
std::hash< underlying_type > hasher;
return hasher( static_cast< underlying_type >( arg ) );
}
};
}
을 사용 std::unordered_map
하면 해시 함수가 필요하다는 것을 알 수 있습니다. 내장 또는 STL
유형의 경우 사용 가능한 기본값이 있지만 사용자 정의 유형에는 사용할 수 없습니다. 지도 만 필요하다면 시도해 보지 않겠 std::map
습니까?
MyEnumClass를 정의하는 헤더에 다음을 추가하십시오.
namespace std {
template <> struct hash<MyEnumClass> {
size_t operator() (const MyEnumClass &t) const { return size_t(t); }
};
}
시험
std::unordered_map<Shader::Type, Shader, std::hash<std::underlying_type<Shader::Type>::type>> shaders;
참고 URL : https://stackoverflow.com/questions/18837857/cant-use-enum-class-as-unordered-map-key
'Program Tip' 카테고리의 다른 글
Android 애플리케이션에 외부 글꼴을 추가하는 방법 (0) | 2020.10.28 |
---|---|
height : 100 % 또는 min-height : html 및 body 요소의 경우 100 %? (0) | 2020.10.28 |
Android 스튜디오 오류 : Error : CreateProcess error = 216,이 버전의 % 1은 실행중인 Windows 버전과 호환되지 않습니다. (0) | 2020.10.28 |
accepts_nested_attributes_for 하위 연결 유효성 검사 실패 (0) | 2020.10.28 |
자바 단위 테스트, 디렉토리 레이아웃 (0) | 2020.10.28 |