如何在没有宏的情况下正确使用NED Trie
How to correctly use NED-Trie without macro?
我正在尝试使用NED Trie,它只有一个头文件。如何在不使用NEDTRIE_*
宏的情况下使用此库?并迭代从CCD_ 2中得到密钥和值?在trie_iterator
上似乎不存在first
和second
性质
#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.
免责声明:我是nedtries的作者。你应该用nedtries标记这个问题,这样我会更快地看到它。
在trie_map中,除了size_t之外,您不能使用任何东西作为键,因为底层的C宏实现只能使用size_t键。这是因为它依赖于位扫描CPU操作码,而这些操作码需要size_t。如果IEEE 754是一种稳定的二进制格式,您可以通过将其强制转换为size_t来将其与double一起使用,但事实并非如此,因此您无法安全地执行此操作。
正如文档所说,通过std::hash传递任何非size_t密钥,并在取消引用后检查是否存在冲突。关于trie_map没有提供第一个和第二个,好吧,trie_map是一堆垃圾代码。我在文档中确实说过不要使用它。如果你检查源代码,你会发现我做了大量非法和未定义的行为,所有这些都是你应该避免在代码库中使用的。也就是说,作为"如果?"场景的快速原型,特别是"逐位尝试真的会帮助我的C++代码吗?",它符合要求。
Boost C++库已经在Trie STL容器上做了一些工作,最近一次是在2013年的GSoC中。不过还没有准备好生产。遗憾的是,C++真的可以用一个合适的trie STL容器。
Niall
相关文章:
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 在 c++ 中实现 Trie 时出现分段错误
- Trie*& 和 Trie** 的意思是 Same?
- Trie 树初始化
- 在我的trie实现中出现分段错误
- 使用 trie 数据结构链接不同类型的信息
- C++ 中的 TRIE 数据结构实现
- Trie数据结构的实现
- C++Trie中的浮点异常
- C ++无法让Trie给出正确的搜索词
- 在不创建新节点的情况下实现带有映射的trie
- 为什么此代码在此 Trie 实现中使用映射 c++ 中的指针崩溃?
- 是否有一个很好的方法可以在C 11中打印出像JSON一样的Trie结构(仅迭代解决方案)的扁平命名空间
- 如何为 Trie 树编写析构函数
- C 深度首次使用前缀参数对Trie进行了搜索
- Trie 查找/添加功能无法正常工作
- 打印出使用地图实现的Trie中的所有单词
- 使用 Trie 自动完成
- 关于 TRIE 的 Leetcode 208。我的解构器有什么问题?它永远不会起作用
- 如何在没有宏的情况下正确使用NED Trie