草庐IT

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

coder 2023-11-16 原文

最近我更喜欢使用 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

最佳答案

您需要在 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;

关于c++ - glm::ivec2 作为无序映射中的键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9047612/

有关c++ - glm::ivec2 作为无序映射中的键的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  3. ruby - 检查字符串是否包含散列中的任何键并返回它包含的键的值 - 2

    我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案

  4. ruby - 字符串文字中的转义状态作为 `String#tr` 的参数 - 2

    对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一

  5. ruby - 在哈希的键数组中追加元素 - 2

    查看我的Ruby代码:h=Hash.new([])h[0]=:word1h[1]=h[1]输出是:Hash={0=>:word1,1=>[:word2,:word3],2=>[:word2,:word3]}我希望有Hash={0=>:word1,1=>[:word2],2=>[:word3]}为什么要附加第二个哈希元素(数组)?如何将新数组元素附加到第三个哈希元素? 最佳答案 如果您提供单个值作为Hash.new的参数(例如Hash.new([]),完全相同的对象将用作每个缺失键的默认值。这就是您所拥有的,那是你不想要的。您可以改用

  6. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  7. ruby-on-rails - 应用程序的名称是否可以作为变量使用? - 2

    当我创建一个Rails应用程序时,控制台:railsnewfoo我的代码可以使用字符串“foo”吗?puts"Yourapp'snameis"+app_name_bar 最佳答案 Rails.application.class将为您提供应用程序的全名(例如YourAppName::Application)。从那里您可以使用Rails.application.class.parent获取模块名称。 关于ruby-on-rails-应用程序的名称是否可以作为变量使用?,我们在StackOve

  8. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  9. ruby-on-rails - 使用作为方法的值在 ruby​​ 中搜索哈希 - 2

    我在搜索我的值是方法的散列时遇到问题。我只是不想运行plan_type与键匹配的方法。defmethod(plan_type,plan,user){foo:plan_is_foo(plan,user),bar:plan_is_bar(plan,user),waa:plan_is_waa(plan,user),har:plan_is_har(user)}[plan_type]end目前如果我传入“bar”作为plan_type,所有方法都会运行,我怎么能只运行plan_is_bar方法呢? 最佳答案 这个变体怎么样?defmethod

  10. ruby - 无法在 Ruby 中将 ffmpeg 作为子进程运行 - 2

    我正在尝试使用以下代码通过将ffmpeg实用程序作为子进程运行并获取其输出并解析它来确定视频分辨率:IO.popen'ffmpeg-i'+path_to_filedo|ffmpegIO|#myparsegoeshereend...但是ffmpeg输出仍然连接到标准输出并且ffmepgIO.readlines是空的。ffmpeg实用程序是否需要一些特殊处理?或者还有其他方法可以获得ffmpeg输出吗?我在WinXP和FedoraLinux下测试了这段代码-结果是一样的。 最佳答案 要跟进mouviciel的评论,您需要使用类似pope

随机推荐