glm::ivec2 作为无序映射中的键

发布于 2024-12-29 16:28:42 字数 11790 浏览 0 评论 0原文

最近,我更多地使用 Scala 编程语言而不是 C++,现在我对移植一行非常简单的代码感到沮丧,

val map = new HashMap[Vec2i,Entity]

它只是拒绝在 C++ 中编译,并出现奇怪的模板错误。 C++ 中 Vec2i 的等价物是 glm::ivec2,它基本上是一个包含两个整数和一些数学运算符的结构。

这就是我得到的结果:

#include <iostream>
#include <unordered_map>
#include <glm/glm.hpp>

using namespace std;
using namespace glm;

struct KeyTraits {
size_t operator()(const ivec2& k) {
        return std::hash<int>()(k.x) ^ std::hash<int>()(k.y);
    }

bool operator()(const ivec2& a, const ivec2& b) {
        return a.x == b.x && a.y == b.y;
    }
};

typedef unordered_map<ivec2,int,KeyTraits,KeyTraits> MyMap;

int main(int argc, char **argv)
{
    MyMap map;

    map[ivec2(2,3)] = 7;
    map[ivec2(3,4)] = 8;

    for(auto it = map.begin(); it != map.end(); it++) {
        cout << it->second << endl;
    }
}

当前的编译错误是:

In file included from /usr/include/c++/4.5/bits/hashtable.h:35:0,
             from /usr/include/c++/4.5/unordered_map:45,
             from /home/arne/codelite/LanguageTest/main.cpp:2:
/usr/include/c++/4.5/bits/hashtable_policy.h: In member function ‘std::__detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, std::__detail::_Default_ranged_hash, false>::_Hash_code_type std::__detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, std::__detail::_Default_ranged_hash, false>::_M_hash_code(const _Key&) const [with _Key = glm::detail::tvec2<int>, _Value = std::pair<const glm::detail::tvec2<int>, int>, _ExtractKey = std::_Select1st<std::pair<const glm::detail::tvec2<int>, int> >, _Equal = KeyTraits, _H1 = KeyTraits, _H2 = std::__detail::_Mod_range_hashing, std::__detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, std::__detail::_Default_ranged_hash, false>::_Hash_code_type = long unsigned int]’:
/usr/include/c++/4.5/bits/hashtable_policy.h:535:74:   instantiated from ‘std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::mapped_type& std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::operator[](const _Key&) [with _Key = glm::detail::tvec2<int>, _Pair = std::pair<const glm::detail::tvec2<int>, int>, _Hashtable = std::_Hashtable<glm::detail::tvec2<int>, std::pair<const glm::detail::tvec2<int>, int>, std::allocator<std::pair<const glm::detail::tvec2<int>, int> >, std::_Select1st<std::pair<const glm::detail::tvec2<int>, int> >, KeyTraits, KeyTraits, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, false, false, true>, std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::mapped_type = int]’
/home/arne/codelite/LanguageTest/main.cpp:24:16:   instantiated from here
/usr/include/c++/4.5/bits/hashtable_policy.h:727:25: error: passing ‘const KeyTraits’ as ‘this’ argument of ‘size_t KeyTraits::operator()(const glm::core::type::ivec2&)’ discards qualifiers
/usr/include/c++/4.5/bits/hashtable_policy.h: In member function ‘bool std::__detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, std::__detail::_Default_ranged_hash, false>::_M_compare(const _Key&, std::__detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, std::__detail::_Default_ranged_hash, false>::_Hash_code_type, std::__detail::_Hash_node<_Value, false>*) const [with _Key = glm::detail::tvec2<int>, _Value = std::pair<const glm::detail::tvec2<int>, int>, _ExtractKey = std::_Select1st<std::pair<const glm::detail::tvec2<int>, int> >, _Equal = KeyTraits, _H1 = KeyTraits, _H2 = std::__detail::_Mod_range_hashing, std::__detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, std::__detail::_Default_ranged_hash, false>::_Hash_code_type = long unsigned int]’:
/usr/include/c++/4.5/bits/hashtable.h:879:2:   instantiated from ‘std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_Node* std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_M_find_node(std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_Node*, const key_type&, typename std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_Hash_code_type) const [with _Key = glm::detail::tvec2<int>, _Value = std::pair<const glm::detail::tvec2<int>, int>, _Allocator = std::allocator<std::pair<const glm::detail::tvec2<int>, int> >, _ExtractKey = std::_Select1st<std::pair<const glm::detail::tvec2<int>, int> >, _Equal = KeyTraits, _H1 = KeyTraits, _H2 = std::__detail::_Mod_range_hashing, _Hash = std::__detail::_Default_ranged_hash, _RehashPolicy = std::__detail::_Prime_rehash_policy, bool __cache_hash_code = false, bool __constant_iterators = false, bool __unique_keys = true, std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_Node = std::__detail::_Hash_node<std::pair<const glm::detail::tvec2<int>, int>, false>, key_type = glm::detail::tvec2<int>, typename std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_Hash_code_type = long unsigned int]’
/usr/include/c++/4.5/bits/hashtable_policy.h:540:53:   instantiated from ‘std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::mapped_type& std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::operator[](const _Key&) [with _Key = glm::detail::tvec2<int>, _Pair = std::pair<const glm::detail::tvec2<int>, int>, _Hashtable = std::_Hashtable<glm::detail::tvec2<int>, std::pair<const glm::detail::tvec2<int>, int>, std::allocator<std::pair<const glm::detail::tvec2<int>, int> >, std::_Select1st<std::pair<const glm::detail::tvec2<int>, int> >, KeyTraits, KeyTraits, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, false, false, true>, std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::mapped_type = int]’
/home/arne/codelite/LanguageTest/main.cpp:24:16:   instantiated from here
/usr/include/c++/4.5/bits/hashtable_policy.h:742:48: error: passing ‘const KeyTraits’ as ‘this’ argument of ‘bool KeyTraits::operator()(const glm::core::type::ivec2&, const glm::core::type::ivec2&)’ discards qualifiers
/usr/include/c++/4.5/bits/hashtable_policy.h: In member function ‘size_t std::__detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, std::__detail::_Default_ranged_hash, false>::_M_bucket_index(const std::__detail::_Hash_node<_Value, false>*, size_t) const [with _Key = glm::detail::tvec2<int>, _Value = std::pair<const glm::detail::tvec2<int>, int>, _ExtractKey = std::_Select1st<std::pair<const glm::detail::tvec2<int>, int> >, _Equal = KeyTraits, _H1 = KeyTraits, _H2 = std::__detail::_Mod_range_hashing, size_t = long unsigned int]’:
/usr/include/c++/4.5/bits/hashtable.h:1170:59:   instantiated from ‘void std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_M_rehash(std::_Hashtable::size_type) [with _Key = glm::detail::tvec2<int>, _Value = std::pair<const glm::detail::tvec2<int>, int>, _Allocator = std::allocator<std::pair<const glm::detail::tvec2<int>, int> >, _ExtractKey = std::_Select1st<std::pair<const glm::detail::tvec2<int>, int> >, _Equal = KeyTraits, _H1 = KeyTraits, _H2 = std::__detail::_Mod_range_hashing, _Hash = std::__detail::_Default_ranged_hash, _RehashPolicy = std::__detail::_Prime_rehash_policy, bool __cache_hash_code = false, bool __constant_iterators = false, bool __unique_keys = true, std::_Hashtable::size_type = long unsigned int]’
/usr/include/c++/4.5/bits/hashtable.h:911:8:   instantiated from ‘std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::iterator std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_M_insert_bucket(const value_type&, std::_Hashtable::size_type, typename std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_Hash_code_type) [with _Key = glm::detail::tvec2<int>, _Value = std::pair<const glm::detail::tvec2<int>, int>, _Allocator = std::allocator<std::pair<const glm::detail::tvec2<int>, int> >, _ExtractKey = std::_Select1st<std::pair<const glm::detail::tvec2<int>, int> >, _Equal = KeyTraits, _H1 = KeyTraits, _H2 = std::__detail::_Mod_range_hashing, _Hash = std::__detail::_Default_ranged_hash, _RehashPolicy = std::__detail::_Prime_rehash_policy, bool __cache_hash_code = false, bool __constant_iterators = false, bool __unique_keys = true, std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::iterator = std::__detail::_Hashtable_iterator<std::pair<const glm::detail::tvec2<int>, int>, false, false>, value_type = std::pair<const glm::detail::tvec2<int>, int>, std::_Hashtable::size_type = long unsigned int, typename std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_Hash_code_type = long unsigned int]’
/usr/include/c++/4.5/bits/hashtable_policy.h:543:24:   instantiated from ‘std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::mapped_type& std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::operator[](const _Key&) [with _Key = glm::detail::tvec2<int>, _Pair = std::pair<const glm::detail::tvec2<int>, int>, _Hashtable = std::_Hashtable<glm::detail::tvec2<int>, std::pair<const glm::detail::tvec2<int>, int>, std::allocator<std::pair<const glm::detail::tvec2<int>, int> >, std::_Select1st<std::pair<const glm::detail::tvec2<int>, int> >, KeyTraits, KeyTraits, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, false, false, true>, std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::mapped_type = int]’
/home/arne/codelite/LanguageTest/main.cpp:24:16:   instantiated from here
/usr/include/c++/4.5/bits/hashtable_policy.h:737:55: error: passing ‘const KeyTraits’ as ‘this’ argument of ‘size_t KeyTraits::operator()(const glm::core::type::ivec2&)’ discards qualifiers

lately I am more a user of the Scala Programming Language than C++, And now I am frustrated in porting a very simple line of code

val map = new HashMap[Vec2i,Entity]

it simply refuses to compile in C++ with strange template errors. The equivalent of Vec2i in C++ is glm::ivec2, it is basicly a struct with two integers and some operators for math.

this is how far i got:

#include <iostream>
#include <unordered_map>
#include <glm/glm.hpp>

using namespace std;
using namespace glm;

struct KeyTraits {
size_t operator()(const ivec2& k) {
        return std::hash<int>()(k.x) ^ std::hash<int>()(k.y);
    }

bool operator()(const ivec2& a, const ivec2& b) {
        return a.x == b.x && a.y == b.y;
    }
};

typedef unordered_map<ivec2,int,KeyTraits,KeyTraits> MyMap;

int main(int argc, char **argv)
{
    MyMap map;

    map[ivec2(2,3)] = 7;
    map[ivec2(3,4)] = 8;

    for(auto it = map.begin(); it != map.end(); it++) {
        cout << it->second << endl;
    }
}

The current compile error is:

In file included from /usr/include/c++/4.5/bits/hashtable.h:35:0,
             from /usr/include/c++/4.5/unordered_map:45,
             from /home/arne/codelite/LanguageTest/main.cpp:2:
/usr/include/c++/4.5/bits/hashtable_policy.h: In member function ‘std::__detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, std::__detail::_Default_ranged_hash, false>::_Hash_code_type std::__detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, std::__detail::_Default_ranged_hash, false>::_M_hash_code(const _Key&) const [with _Key = glm::detail::tvec2<int>, _Value = std::pair<const glm::detail::tvec2<int>, int>, _ExtractKey = std::_Select1st<std::pair<const glm::detail::tvec2<int>, int> >, _Equal = KeyTraits, _H1 = KeyTraits, _H2 = std::__detail::_Mod_range_hashing, std::__detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, std::__detail::_Default_ranged_hash, false>::_Hash_code_type = long unsigned int]’:
/usr/include/c++/4.5/bits/hashtable_policy.h:535:74:   instantiated from ‘std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::mapped_type& std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::operator[](const _Key&) [with _Key = glm::detail::tvec2<int>, _Pair = std::pair<const glm::detail::tvec2<int>, int>, _Hashtable = std::_Hashtable<glm::detail::tvec2<int>, std::pair<const glm::detail::tvec2<int>, int>, std::allocator<std::pair<const glm::detail::tvec2<int>, int> >, std::_Select1st<std::pair<const glm::detail::tvec2<int>, int> >, KeyTraits, KeyTraits, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, false, false, true>, std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::mapped_type = int]’
/home/arne/codelite/LanguageTest/main.cpp:24:16:   instantiated from here
/usr/include/c++/4.5/bits/hashtable_policy.h:727:25: error: passing ‘const KeyTraits’ as ‘this’ argument of ‘size_t KeyTraits::operator()(const glm::core::type::ivec2&)’ discards qualifiers
/usr/include/c++/4.5/bits/hashtable_policy.h: In member function ‘bool std::__detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, std::__detail::_Default_ranged_hash, false>::_M_compare(const _Key&, std::__detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, std::__detail::_Default_ranged_hash, false>::_Hash_code_type, std::__detail::_Hash_node<_Value, false>*) const [with _Key = glm::detail::tvec2<int>, _Value = std::pair<const glm::detail::tvec2<int>, int>, _ExtractKey = std::_Select1st<std::pair<const glm::detail::tvec2<int>, int> >, _Equal = KeyTraits, _H1 = KeyTraits, _H2 = std::__detail::_Mod_range_hashing, std::__detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, std::__detail::_Default_ranged_hash, false>::_Hash_code_type = long unsigned int]’:
/usr/include/c++/4.5/bits/hashtable.h:879:2:   instantiated from ‘std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_Node* std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_M_find_node(std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_Node*, const key_type&, typename std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_Hash_code_type) const [with _Key = glm::detail::tvec2<int>, _Value = std::pair<const glm::detail::tvec2<int>, int>, _Allocator = std::allocator<std::pair<const glm::detail::tvec2<int>, int> >, _ExtractKey = std::_Select1st<std::pair<const glm::detail::tvec2<int>, int> >, _Equal = KeyTraits, _H1 = KeyTraits, _H2 = std::__detail::_Mod_range_hashing, _Hash = std::__detail::_Default_ranged_hash, _RehashPolicy = std::__detail::_Prime_rehash_policy, bool __cache_hash_code = false, bool __constant_iterators = false, bool __unique_keys = true, std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_Node = std::__detail::_Hash_node<std::pair<const glm::detail::tvec2<int>, int>, false>, key_type = glm::detail::tvec2<int>, typename std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_Hash_code_type = long unsigned int]’
/usr/include/c++/4.5/bits/hashtable_policy.h:540:53:   instantiated from ‘std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::mapped_type& std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::operator[](const _Key&) [with _Key = glm::detail::tvec2<int>, _Pair = std::pair<const glm::detail::tvec2<int>, int>, _Hashtable = std::_Hashtable<glm::detail::tvec2<int>, std::pair<const glm::detail::tvec2<int>, int>, std::allocator<std::pair<const glm::detail::tvec2<int>, int> >, std::_Select1st<std::pair<const glm::detail::tvec2<int>, int> >, KeyTraits, KeyTraits, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, false, false, true>, std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::mapped_type = int]’
/home/arne/codelite/LanguageTest/main.cpp:24:16:   instantiated from here
/usr/include/c++/4.5/bits/hashtable_policy.h:742:48: error: passing ‘const KeyTraits’ as ‘this’ argument of ‘bool KeyTraits::operator()(const glm::core::type::ivec2&, const glm::core::type::ivec2&)’ discards qualifiers
/usr/include/c++/4.5/bits/hashtable_policy.h: In member function ‘size_t std::__detail::_Hash_code_base<_Key, _Value, _ExtractKey, _Equal, _H1, _H2, std::__detail::_Default_ranged_hash, false>::_M_bucket_index(const std::__detail::_Hash_node<_Value, false>*, size_t) const [with _Key = glm::detail::tvec2<int>, _Value = std::pair<const glm::detail::tvec2<int>, int>, _ExtractKey = std::_Select1st<std::pair<const glm::detail::tvec2<int>, int> >, _Equal = KeyTraits, _H1 = KeyTraits, _H2 = std::__detail::_Mod_range_hashing, size_t = long unsigned int]’:
/usr/include/c++/4.5/bits/hashtable.h:1170:59:   instantiated from ‘void std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_M_rehash(std::_Hashtable::size_type) [with _Key = glm::detail::tvec2<int>, _Value = std::pair<const glm::detail::tvec2<int>, int>, _Allocator = std::allocator<std::pair<const glm::detail::tvec2<int>, int> >, _ExtractKey = std::_Select1st<std::pair<const glm::detail::tvec2<int>, int> >, _Equal = KeyTraits, _H1 = KeyTraits, _H2 = std::__detail::_Mod_range_hashing, _Hash = std::__detail::_Default_ranged_hash, _RehashPolicy = std::__detail::_Prime_rehash_policy, bool __cache_hash_code = false, bool __constant_iterators = false, bool __unique_keys = true, std::_Hashtable::size_type = long unsigned int]’
/usr/include/c++/4.5/bits/hashtable.h:911:8:   instantiated from ‘std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::iterator std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_M_insert_bucket(const value_type&, std::_Hashtable::size_type, typename std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_Hash_code_type) [with _Key = glm::detail::tvec2<int>, _Value = std::pair<const glm::detail::tvec2<int>, int>, _Allocator = std::allocator<std::pair<const glm::detail::tvec2<int>, int> >, _ExtractKey = std::_Select1st<std::pair<const glm::detail::tvec2<int>, int> >, _Equal = KeyTraits, _H1 = KeyTraits, _H2 = std::__detail::_Mod_range_hashing, _Hash = std::__detail::_Default_ranged_hash, _RehashPolicy = std::__detail::_Prime_rehash_policy, bool __cache_hash_code = false, bool __constant_iterators = false, bool __unique_keys = true, std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::iterator = std::__detail::_Hashtable_iterator<std::pair<const glm::detail::tvec2<int>, int>, false, false>, value_type = std::pair<const glm::detail::tvec2<int>, int>, std::_Hashtable::size_type = long unsigned int, typename std::_Hashtable<_Key, _Value, _Allocator, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, __cache_hash_code, __constant_iterators, __unique_keys>::_Hash_code_type = long unsigned int]’
/usr/include/c++/4.5/bits/hashtable_policy.h:543:24:   instantiated from ‘std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::mapped_type& std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::operator[](const _Key&) [with _Key = glm::detail::tvec2<int>, _Pair = std::pair<const glm::detail::tvec2<int>, int>, _Hashtable = std::_Hashtable<glm::detail::tvec2<int>, std::pair<const glm::detail::tvec2<int>, int>, std::allocator<std::pair<const glm::detail::tvec2<int>, int> >, std::_Select1st<std::pair<const glm::detail::tvec2<int>, int> >, KeyTraits, KeyTraits, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, false, false, true>, std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::mapped_type = int]’
/home/arne/codelite/LanguageTest/main.cpp:24:16:   instantiated from here
/usr/include/c++/4.5/bits/hashtable_policy.h:737:55: error: passing ‘const KeyTraits’ as ‘this’ argument of ‘size_t KeyTraits::operator()(const glm::core::type::ivec2&)’ discards qualifiers

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

度的依靠╰つ 2025-01-05 16:28:42

您需要在 typedef 中指定哈希类和比较器类。
请参阅此处的模板参数 Hash 和 KeyEqual:
http://en.cppreference.com/w/cpp/container/unordered_map

它看起来像这样(考虑方法签名末尾的 const 限定符):

struct KeyFuncs
{
    size_t operator()(const ivec2& k)const
    {
        return std::hash<int>()(k.x) ^ std::hash<int>()(k.y);
    }

    bool operator()(const ivec2& a, const ivec2& b)const
    {
            return a.x == b.x && a.y == b.y;
    }
};


typedef unordered_map<ivec2,int,KeyFuncs,KeyFuncs> MyMap;

You need to specify a hash class and a comparator class in your typedef.
See template params Hash and KeyEqual here:
http://en.cppreference.com/w/cpp/container/unordered_map

it will look like that (consider the const qualifiers at the end of the method signatures):

struct KeyFuncs
{
    size_t operator()(const ivec2& k)const
    {
        return std::hash<int>()(k.x) ^ std::hash<int>()(k.y);
    }

    bool operator()(const ivec2& a, const ivec2& b)const
    {
            return a.x == b.x && a.y == b.y;
    }
};


typedef unordered_map<ivec2,int,KeyFuncs,KeyFuncs> MyMap;
忘年祭陌 2025-01-05 16:28:42

哈希值内置于 glm 库中,但是它们是扩展的一部分,因此只需在包含 glm 后执行此操作,然后您就不需要编写自己的哈希值:

#define GLM_ENABLE_EXPERIMENTAL
#include "glm/gtx/hash.hpp"

hashes are built in to the glm library, however they are part of the exensions so just do this after you include glm and then you won't need to write your own hash:

#define GLM_ENABLE_EXPERIMENTAL
#include "glm/gtx/hash.hpp"
别把无礼当个性 2025-01-05 16:28:42

只需查看链接器错误,它就会告诉您应该在模板参数列表中实现或提供什么:

std::hash<glm::detail::tvec2<int> >::operator()(glm::detail::tvec2<int>) const

程序不知道如何基于向量对象创建哈希。您必须计算自己的哈希值,以便地图代码能够区分向量。

编辑:
我倾向于使用指向向量的指针,因为如果您添加一些元素并稍后更改它,这可能会搞砸(所以您应该添加 const 对象)。


编辑2:
使用更新的代码/错误消息,您似乎忘记将 KeyTaits 中的方法设置为 const,因此它们的 this 指针的类型为 KeyTraits*,但传递的值应该是 const KeyTraits*

Just look at the linker error, it tells you what you should implement or provide in the list of template arguments:

std::hash<glm::detail::tvec2<int> >::operator()(glm::detail::tvec2<int>) const

The program doesn't know how to create a hash based on the vector object. You'd have to calculate your own hash, so the map code is able to differentiate between vectors.

Edit:
I'd tend to use pointers to vectors, as this might screw up if you add some element and change it later on (so you should add const objects).


Edit 2:
With the updated code/error message, it seems like you forgot to make the methods inside KeyTaits const, so their this pointer is of type KeyTraits*, but the value passed is meant to be const KeyTraits*.

若水般的淡然安静女子 2025-01-05 16:28:42

我相信“fire in thehole”中的答案是最好的答案。

但是,只是想指出使用 std::string_view 的替代解决方案。

namespace std
{
template <glm::length_t N, typename T, glm::qualifier Q>
struct hash<glm::vec<N, T, Q>>
{
    typedef hash<glm::vec<N, T, Q>> VecT;
    std::size_t operator()(const VecT& v) const {
        return std::hash(std::string_view((const char*)&v, sizeof(v)));
    }
};
}

好的想法是,该解决方案可以轻松适应任何其他纯数据类型。

I believe the answer from "fire in the hole" is the best one.

However, just wanted to point out an alternative solution using std::string_view.

namespace std
{
template <glm::length_t N, typename T, glm::qualifier Q>
struct hash<glm::vec<N, T, Q>>
{
    typedef hash<glm::vec<N, T, Q>> VecT;
    std::size_t operator()(const VecT& v) const {
        return std::hash(std::string_view((const char*)&v, sizeof(v)));
    }
};
}

Good think is that this solution can be easily adapted to any other plain data types.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文