c++ - C++ 中 unordered_map 的包装类

标签 c++ templates

我正在尝试在 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 , ValHash = 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/

相关文章:

c++ - 如何从 IP Camera 的 Motion Jpeg Stream 中提取图像?

c++ - 为什么我不能用非引用返回类型定义 operator=?

PHP 与模板引擎

c++ - 通过 C++ 实现容器元素总和的模板函数

C++ 模板跟踪器

C++如何在不复制的情况下将元素存储在双端队列中

c++ - vector 类型值不匹配错误

c++ - streamsize prec = cout.precision(); 的重点是什么?和以下几行?

c++ - 成员函数的模板类和类型返回类型

PHP:函数中的函数然后包含在内部函数中