我正在尝试在 unordered_map 上实现一个包装器类。
#include <iostream>
#include <unordered_map>
using namespace std;
template< class Key > class HashFn
{
public:
size_t operator() (Key & inKey);
};
template<> size_t HashFn< string >::operator()(string & inKey)
{
return std::hash<string>{}(inKey);
}
template< class Key, class Val, class Hash = HashFn< Key > > class unordered_map_wrapper
{
private:
unordered_map<Key, Val, Hash> * mTable;
public:
unordered_map_wrapper( );
bool insert( pair<Key, Val> & inPair );
};
template< class Key, class Val, class Hash > unordered_map_wrapper< Key, Val, Hash >::unordered_map_wrapper( )
{
mTable = new unordered_map< Key, Val, Hash >( );
}
template< class Key, class Val, class Hash > bool unordered_map_wrapper< Key, Val, Hash >::insert( pair<Key, Val> & inPair )
{
//internal implementation
return NULL;
}
int main() {
unordered_map_wrapper< string,unsigned > h();
h.insert(std::make_pair< string,unsigned >( "One", 1 ));
return 0;
}
这里的 hash 函数是在模板类 Key
上模板化的.
unordered_map_wrapper 模板类的标识符是 Key
, Val
和 Hash = HashFn< Key >
.
在这里,我们默认使用字符串的模板特化并传递 HashFn class
(模板类)作为默认参数。
当我们将它作为字符串插入时,我们使用了重载的 operator()
。作为专业。
如果HashFn
类没有模板化,如果我们只使用 string
作为一个没有模板的具体实现,它是有效的。
但是当我们使用模板时,出现编译错误:
test.cpp: In function ‘int main()’:
test.cpp:40:7: error: request for member ‘insert’ in ‘h’, which is of non-class type ‘unordered_map_wrapper<std::__cxx11::basic_string<char>, unsigned int>()’
h.insert(std::make_pair< string,unsigned >( "One", 1 ));
^~~~~~
我们似乎无法检测到 hashFn
中字符串的模板特化类(class)。
此问题仅在 h.insert()
时出现被调用还是我们遗漏了什么。
请提出出路。 提前致谢!
最佳答案
你真的应该开始添加 const
在你的代码中。但让我们从头开始:
<强>1。最烦人的解析
test.cpp:41:5: error: base of member reference is a function; perhaps you meant to call it with no arguments?
指的是
unordered_map_wrapper< string,unsigned > h();
这一行可以理解为 h
的函数声明,不考虑参数,返回一个 unordered_map_wrapper<string, unsigned>
.或者它可以是变量声明 h
, 使用默认构造函数和类型 unordered_map_wrapper<string, unsigned>
.标准说,它是第一个。
要么不使用括号,要么不使用大括号。检查最烦人的解析。
<强>2。使用 const
(1)
test.cpp:41:14: error: non-const lvalue reference to type 'pair<...>' cannot bind to a temporary of type 'pair<...>'
[...]
指的是
bool insert( pair<Key, Val> & inPair );
你的 insert
引用 pair<Key, Val>
,在你的情况下你传递了一个 rvlaue,所以你不能绑定(bind)它。您应该使用通用引用或常量引用。所以,最简单的解决方法是使用
bool insert( const pair<Key, Val> & inPair );
<强>3。使用 const
(2)
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../include/c++/6.3.1/bits/hashtable_policy.h:85:11: error: no matching function for
call to object of type 'const HashFn<std::__cxx11::basic_string<char> >'
[...]
指的是您的哈希函数 - 它无法对您的 key 进行哈希处理。
这又是由于缺少const
秒。你的哈希函数应该有签名
size_t operator() (const Key & inKey) const;
结论
您的最终代码应如下所示:
#include <iostream>
#include <unordered_map>
using namespace std;
template <class Key> class HashFn {
public:
size_t operator()(const Key &inKey) const;
};
template <> size_t HashFn<string>::operator()(const string &inKey) const {
return std::hash<string>{}(inKey);
}
template <class Key, class Val, class Hash = HashFn<Key>>
class unordered_map_wrapper {
private:
unordered_map<Key, Val, Hash> *mTable;
public:
unordered_map_wrapper();
bool insert(const pair<Key, Val> &inPair);
};
template <class Key, class Val, class Hash>
unordered_map_wrapper<Key, Val, Hash>::unordered_map_wrapper() {
mTable = new unordered_map<Key, Val, Hash>();
}
template <class Key, class Val, class Hash>
bool unordered_map_wrapper<Key, Val, Hash>::insert(
const pair<Key, Val> &inPair) {
return mTable->insert(inPair).second;
}
int main() {
unordered_map_wrapper<string, unsigned> h{};
h.insert(std::make_pair<string, unsigned>("One", 1));
return 0;
}
我没有检查你现在是否使用 const
尽你所能,但你真的应该开始这样做。
关于c++ - C++ 中 unordered_map 的包装类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42653586/