ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

c – std :: unordered_map :: find使用与Key类型不同的类型?

2019-09-30 08:04:06  阅读:202  来源: 互联网

标签:unordered-map c c11


我有一个使用字符串类型作为键的unordered_map:

std::unordered_map<string, value> map;

为字符串提供了std :: hash特化,以及a
合适的操作符==.

现在我还有一个“字符串视图”类,它是一个指向现有字符串的弱指针,避免了堆分配:

class string_view {
    string *data;
    size_t begin, len;
    // ...
};  

现在,我希望能够使用string_view对象检查地图中是否存在密钥.不幸的是,std :: unordered_map :: find采用Key参数,而不是泛型T参数.

(当然,我可以“提升”一个字符串,但这会导致我想避免的分配.)

我喜欢的是类似的东西

template<class Key, class Value>
class unordered_map
{
    template<class T> iterator find(const T &t);
};

这将需要适当地定义operator ==(T,Key)和std :: hash< T>(),并将迭代器返回到匹配值.

有没有解决方法?

解决方法:

如上所述,C 14不为std :: unordered_map提供异构查找(与std :: map不同).您可以使用Boost.MultiIndex来定义std :: unordered_map的相当接近的替代,它允许您在不分配临时std :: strings的情况下查找string_views:

Live Coliru Demo

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
#include <string>

using namespace boost::multi_index;

struct string_view
{
  std::string *data;
  std::size_t begin,len;
};

template<typename T,typename Q>
struct mutable_pair
{
  T         first;
  mutable Q second;
};

struct string_view_hash
{
  std::size_t operator()(const string_view& v)const
  {
     return boost::hash_range(
       v.data->begin()+v.begin,v.data->begin()+v.begin+v.len);
  }
  std::size_t operator()(const std::string& s)const
  {
     return boost::hash_range(s.begin(),s.end());
  }
};

struct string_view_equal_to
{
  std::size_t operator()(const std::string& s1,const std::string& s2)const
  {
     return s1==s2;
  }
  std::size_t operator()(const std::string& s1,const string_view& v2)const
  {
     return s1.size()==v2.len&&
            std::equal(
              s1.begin(),s1.end(),
              v2.data->begin()+v2.begin);
  }
  std::size_t operator()(const string_view& v1,const std::string& s2)const
  {
     return v1.len==s2.size()&&
            std::equal(
              v1.data->begin()+v1.begin,v1.data->begin()+v1.begin+v1.len,
              s2.begin());
  }
};

template<typename Q>
using unordered_string_map=multi_index_container<
  mutable_pair<std::string,Q>,
  indexed_by<
    hashed_unique<
      member<
        mutable_pair<std::string,Q>,
        std::string,
        &mutable_pair<std::string,Q>::first
      >,
      string_view_hash,
      string_view_equal_to
    >
  >
>;

#include <iostream>

int main()
{
  unordered_string_map<int> m={{"hello",0},{"boost",1},{"bye",2}};

  std::string str="helloboost";
  auto it=m.find(string_view{&str,5,5});
  std::cout<<it->first<<","<<it->second<<"\n";
}

产量

boost,1

标签:unordered-map,c,c11
来源: https://codeday.me/bug/20190930/1835270.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有