【问题标题】:How to correctly use NED-Trie without macro?如何在没有宏的情况下正确使用 NED-Trie?
【发布时间】:2015-04-18 22:02:42
【问题描述】:

我正在尝试使用NED-Trie,它只有一个标头file。 如何在不使用NEDTRIE_* 宏的情况下使用这个库?并迭代以从iterator 获取键和值? trie_iterator 上似乎没有 firstsecond 属性

#include <cstring>
#include "nedtrie.h"
#include <iostream>
#include <string>
using namespace std;
typedef nedtries::trie_map<string,double> MSD;
int main() {
  MSD m;
  m["test"] = 1234;
  m["yay"] = 2345;
  m["foo"] = 3456;
  m["bar"] = 4567;
  for(auto it = m.begin(); it != m.end(); ++it) {
     string key = it->first;
     double val = it->second; 
  } 
}

从错误来看,trie_map 似乎不能与std::string 一起使用?

In file included from nedtrie.cpp:2:
./deps/nedtrie.h:1813:20: error: no viable conversion from 'const std::basic_string<char>' to 'size_t' (aka 'unsigned long')
            return r->key;
                   ^~~~~~
./deps/nedtrie.h:1625:14: note: in instantiation of member function 'nedtries::intern::findkeyfunct_t<std::basic_string<char>, double, nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>,
      std::_List_iterator<unsigned long> >, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double> >::operator()' requested here
      return keyfunct_()(*v);
             ^
./deps/nedtrie.h:611:17: note: in instantiation of function template specialization 'nedtries::intern::to_Ckeyfunct<nedtries::intern::findkeyfunct_t<std::basic_string<char>, double, nedtries::trie_maptype<std::basic_string<char>, double,
      nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> >, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double> >, nedtries::trie_maptype<std::basic_string<char>, double,
      nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> > >' requested here
    size_t rkey=keyfunct(r), keybit, nodekey;
                ^
./deps/nedtrie.h:1898:14: note: in instantiation of function template specialization 'nedtries::triefind<nedtries::trie_map_head<nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>,
      std::_List_iterator<unsigned long> > >, nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> >, 24, &nedtries::intern::to_Ckeyfunct>' requested here
      return triefind<trie_map_head<mapvaluetype>, mapvaluetype, trie_fieldoffset, intern::to_Ckeyfunct<intern::findkeyfunct_t<keytype, type, mapvaluetype, keyfunct> > >(&triehead, (mapvaluetype *) buffer);
             ^
./deps/nedtrie.h:2069:50: note: in instantiation of member function 'nedtries::trie_map<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::allocator<nedtries::trie_maptype<std::basic_string<char>, double,
      nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> > >, nedpolicy::nobblezeros, std::list<nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>,
      double>, std::_List_iterator<unsigned long> >, std::allocator<nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> > > > >::triehead_find' requested here
      mapvaluetype *r=const_cast<mapvaluetype *>(triehead_find(key));
                                                 ^
nedtrie.cpp:9:8: note: in instantiation of member function 'nedtries::trie_map<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::allocator<nedtries::trie_maptype<std::basic_string<char>, double,
      nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> > >, nedpolicy::nobblezeros, std::list<nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>,
      double>, std::_List_iterator<unsigned long> >, std::allocator<nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> > > > >::operator[]' requested here
      m["test"] = 1234;
       ^
In file included from nedtrie.cpp:2:
./deps/nedtrie.h:1814:18: error: no viable conversion from 'std::basic_string<char>' to 'size_t' (aka 'unsigned long')
          return keyfunct()(v);
                 ^~~~~~~~~~~~~
./deps/nedtrie.h:1728:19: warning: unused variable 'ensure_trie_link_offset_is_bounded' [-Wunused-variable]
      static char ensure_trie_link_offset_is_bounded[trie_link_offset+sizeof(trie_link)<=sizeof(*this)];
                  ^
./deps/nedtrie.h:1939:76: note: in instantiation of member function 'nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> >::trie_maptype' requested here
      iterator it=iterator(this, stlcontainer::insert(stlcontainer::end(), std::move(val)));
                                                                           ^
./deps/nedtrie.h:2075:12: note: in instantiation of member function 'nedtries::trie_map<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::allocator<nedtries::trie_maptype<std::basic_string<char>, double,
      nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> > >, nedpolicy::nobblezeros, std::list<nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>,
      double>, std::_List_iterator<unsigned long> >, std::allocator<nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> > > > >::triehead_insert' requested
      here
        it=triehead_insert(key, std::move(type()));
           ^
nedtrie.cpp:9:8: note: in instantiation of member function 'nedtries::trie_map<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::allocator<nedtries::trie_maptype<std::basic_string<char>, double,
      nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> > >, nedpolicy::nobblezeros, std::list<nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>,
      double>, std::_List_iterator<unsigned long> >, std::allocator<nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> > > > >::operator[]' requested here
      m["test"] = 1234;
       ^
In file included from nedtrie.cpp:2:
./deps/nedtrie.h:1625:14: error: no viable conversion from 'std::basic_string<char>' to 'size_t' (aka 'unsigned long')
      return keyfunct_()(*v);
             ^~~~~~~~~~~~~~~
./deps/nedtrie.h:323:17: note: in instantiation of function template specialization 'nedtries::intern::to_Ckeyfunct<nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, nedtries::trie_maptype<std::basic_string<char>, double,
      nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> > >' requested here
    size_t rkey=keyfunct(r), keybit, nodekey;
                ^
./deps/nedtrie.h:1942:7: note: in instantiation of function template specialization 'nedtries::trieinsert<nedtries::trie_map_head<nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>,
      std::_List_iterator<unsigned long> > >, nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> >, 24, &nedtries::intern::to_Ckeyfunct>' requested here
      trieinsert<trie_map_head<mapvaluetype>, mapvaluetype, trie_fieldoffset, intern::to_Ckeyfunct<keyfunct> >(&triehead, const_cast<mapvaluetype *>(&(*it)));
      ^
./deps/nedtrie.h:2075:12: note: in instantiation of member function 'nedtries::trie_map<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::allocator<nedtries::trie_maptype<std::basic_string<char>, double,
      nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> > >, nedpolicy::nobblezeros, std::list<nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>,
      double>, std::_List_iterator<unsigned long> >, std::allocator<nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> > > > >::triehead_insert' requested
      here
        it=triehead_insert(key, std::move(type()));
           ^
nedtrie.cpp:9:8: note: in instantiation of member function 'nedtries::trie_map<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::allocator<nedtries::trie_maptype<std::basic_string<char>, double,
      nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> > >, nedpolicy::nobblezeros, std::list<nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>,
      double>, std::_List_iterator<unsigned long> >, std::allocator<nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> > > > >::operator[]' requested here
      m["test"] = 1234;
       ^
In file included from nedtrie.cpp:2:
./deps/nedtrie.h:1773:9: error: no matching function for call to 'trienext'
        trienext<trie_map_head<mapvaluetype>, mapvaluetype, mapvaluetype::trie_link_offset, intern::to_Ckeyfunct<typename mapvaluetype::trie_keyfunct_type> >(&parent->triehead, (mapvaluetype *)(&**this)) :
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
nedtrie.cpp:13:47: note: in instantiation of member function 'nedtries::trie_iterator<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::allocator<nedtries::trie_maptype<std::basic_string<char>, double,
      nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> > >, nobblezeros, std::list<nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>,
      std::_List_iterator<unsigned long> >, std::allocator<nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> > > >,
      std::_List_iterator<nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> > >, 1, nedtries::trie_maptype<std::basic_string<char>, double,
      nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> >, nedtries::trie_iterator<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>,
      std::allocator<nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> > >, nobblezeros, std::list<nedtries::trie_maptype<std::basic_string<char>, double,
      nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> >, std::allocator<nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>,
      std::_List_iterator<unsigned long> > > >, std::_List_const_iterator<nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> > >, 1,
      nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> >,
      nedtries::intern::noconstiteratortype<std::_List_const_iterator<nedtries::trie_maptype<std::basic_string<char>, double, nedtries::trie_maptype_keyfunct<std::basic_string<char>, double>, std::_List_iterator<unsigned long> > > > > >::operator++' requested
      here
      for(auto it = m.begin(); it != m.end(); ++it) {
                                              ^
./deps/nedtrie.h:1141:120: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'keyfunct'
  template<class trietype, class type, size_t fieldoffset, size_t (*keyfunct)(const type *RESTRICT)> DEBUGINLINE type *trienext(const trietype *RESTRICT head, const type *RESTRICT r)
                                                                                                                       ^
1 warning and 4 errors generated.

【问题讨论】:

  • 从它的 Readme.html "它的两个主要缺点是 (i) 它只能在 size_t (即 void * 的大小)上键入,因此它不能使用任意大的键就像散列表一样(当然可以将大键散列成 size_t 大小的键)"

标签: c++ trie


【解决方案1】:

免责声明:我是 nedtries 的作者。你应该用 nedtries 标记这个问题,然后我会更快地看到它。

除了 size_t 作为 trie_map 中的键之外,您不能使用任何东西,因为底层 C 宏实现仅适用于 size_t 键。这是因为它依赖于位扫描 CPU 操作码,并且这些操作码采用 size_t。如果 IEEE 754 是一种稳定的二进制格式,您可以将其与 double 一起使用,方法是将其转换为 size_t,但由于它不是,因此您无法安全地执行此操作。

正如文档所说,通过 std::hash 传递任何非 size_t 键并在取消引用后检查冲突。关于 trie_map 不提供第一和第二,以及 trie_map 是一堆废话。我确实在文档中说不要使用它。如果你检查源代码,你会发现我做了很多非法和未定义的行为,所有你应该避免在你的代码库中的东西。也就是说,作为“如果?”的快速原型设计者。场景,特别是“按位尝试真的会帮助我的 C++ 代码吗?”,它符合要求。

Boost C++ 库已经在 Trie STL 容器上完成了一些工作,最近一次是在 GSoC 2013 中。不过还没有准备好生产。很遗憾,因为 C++ 确实可以使用适当的 trie STL 容器。

尼尔

【讨论】:

  • 我将补充一点,concurrent_map 实现最好使用按位尝试而不是红黑树来完成,如果我在svn.boost.org/trac/boost/wiki/SoC2015 找到一个非常好的并发哈希表 GSoC 项目学生我'会让他们实现 concurrent_map 作为 Boost 资助的 GSoC 扩展。
  • 以下标签不存在:[nedtrie] [nedtries]。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-12
  • 1970-01-01
  • 2015-11-21
  • 1970-01-01
  • 2015-07-16
相关资源
最近更新 更多