unordered_map包装器中的运算符实现的返回类型不匹配

时间:2017-06-14 11:13:18

标签: c++11 templates stl unordered-map const-iterator

我在std :: unordered_map之上使用用户定义的哈希函数和简单的iterator / const_iterator实现了一个简单的包装器。大多数部件都在工作,但我坚持使用*和 - >运营商实施。从unordered_map运算符的返回类型到我的包装运算符的映射由于类型不匹配错误而遇到编译错误。

基本上,“return internalItr”和“return&(* internalItr)”都会导致类型不匹配。但是,为了测试(注释代码),我在const_iterator类中使用了const成员变量,但随后赋值“return_type = * internalItr”起作用,这基本上是相同的类型转换。但是在const_iterator中保留一个const成员变量对我来说不是一个解决方案,因为它会因“it = h.begin()”中的常量而遇到其他问题。由于遗留库代码,我无法更改任何公共API签名,我的选项有限。我很抱歉发布这个长代码块但是找不到更好的方法来说明我的带有3个模板参数的std :: unordered_map的场景。但是,为了简洁起见,我省略了非兴趣/工作模板实现代码,但包含了提供背景知识的所有api。

感谢您的评论!

template< class Key >
class HashFunction
{
  public:
    HashFunction(){};
    HashFunction( const Key & inKey );
    inline operator unsigned() const
    {
      return hashCode;
    }
    size_t operator()(const Key &inKey) const;
  private:
    unsigned hashCode;
};

template< class Key, class Val, class Hash = HashFunction< Key > >
class unordered_map_wrapper
{
  private:
   typedef typename unordered_map<Key,Val,Hash>::const_iterator int_const_iterator;
   typedef typename unordered_map<Key,Val,Hash>::iterator int_iterator;
  public:
   typedef std::pair< Key, Val > key_value;
   class iterator
   {
     friend class unordered_map_wrapper;
     private:
      iterator( int_iterator & inIterator );
     public:
      iterator();
     private:
      int_iterator internalItr;
   };
   class const_iterator
   {
     friend class unordered_map_wrapper;
     private:
      const_iterator( const int_const_iterator & inIterator );
     public:
      const_iterator();
      const key_value & operator*() const;
      const key_value * operator->() const;
      const_iterator & operator++();
      bool operator!=( const const_iterator & inIterator ) const;
     private:
      int_const_iterator internalItr;
      //const key_value return_type;
   };
   const_iterator begin() const
   {
     return const_iterator( mTable->begin() );
   }
   const_iterator end() const
   {
      return const_iterator( mTable->end() );
   }
   unordered_map_wrapper();
   std::pair< iterator, bool > insert(const key_value & inPair);
  private:
    unordered_map<Key, Val, Hash> * mTable;
};

template< class Key, class Val, class Hash >
unordered_map_wrapper< Key, Val, Hash >::const_iterator::const_iterator()
{
}

template< class Key, class Val, class Hash >
unordered_map_wrapper< Key, Val, Hash >::const_iterator::const_iterator( const int_const_iterator & inIterator ) :
  internalItr( inIterator )
{
}

template< class Key, class Val, class Hash >
unordered_map_wrapper< Key, Val, Hash >::unordered_map_wrapper()
{
    mTable=new unordered_map<Key, Val, Hash>(10);
}

template< class Key, class Val, class Hash >
const typename unordered_map_wrapper< Key, Val, Hash >::key_value & unordered_map_wrapper< Key, Val, Hash >::const_iterator::operator*() const
{
  return *internalItr;
}

template< class Key, class Val, class Hash >
const typename unordered_map_wrapper< Key, Val, Hash >::key_value * unordered_map_wrapper< Key, Val, Hash >::const_iterator::operator->() const
{
  //return internalItr;
  return &(*internalItr);
  //return_type = *internalItr;
  //return &return_type;
}

int main() {
  unordered_map_wrapper<string, unsigned> h;
  unordered_map_wrapper<string, unsigned>::const_iterator it;
  h.insert(std::make_pair<string, unsigned>(string("One"), 1));

  std::cout << "MAP VALUES: " << endl;
  for ( it = h.begin() ; it != h.end(); ++it )
    std::cout << " " << it->first << ":" << it->second << endl;

  return 0;
}

编译错误:

error: cannot convert 'const std::pair<const std::basic_string<char>, unsigned int>*' to 'const key_value* {aka const std::pair<std::basic_string<char>, unsigned int>*}' in return
   return &(*internalItr);                            ^

error: cannot convert 'const int_const_iterator {aka const std::__detail::_Node_const_iterator<std::pair<const std::basic_string<char>, unsigned int>, false, true>}' to 'const key_value* {aka const std::pair<std::basic_string<char>, unsigned int>*}' in return
   return internalItr;
      ^

我可以通过以下方式解决上述问题:

typedef std::pair< const Key, Val > key_value;

但现在遇到其他一些问题。每当我添加另一个nonconst-overloaded begin()时,它就会失败。为什么这不能根据与典型STL容器一起使用的常量来选择正确的begin()?

iterator begin()
   {
     return iterator( mTable->begin());
   }

错误消息是:

prog.cpp:159:22: error: no match for ‘operator=’ (operand types are ‘unordered_map_wrapper<std::__cxx11::basic_string<char>, unsigned int>::const_iterator’ and ‘unordered_map_wrapper<std::__cxx11::basic_string<char>, unsigned int>::iterator’)
   for ( it = h.begin() ; it != h.end(); ++it )

prog.cpp:75:13: error: invalid initialization of non-const reference of type 
‘unordered_map_wrapper<std::__cxx11::basic_string<char>, unsigned 
int>::int_iterator& {aka std::__detail::_Node_iterator<std::pair<const 
std::__cxx11::basic_string<char>, unsigned int>, false, true>&}’ from an 
rvalue of type ‘std::unordered_map<std::__cxx11::basic_string<char>, 
unsigned int, HashFunction<std::__cxx11::basic_string<char> >, 
std::equal_to<std::__cxx11::basic_string<char> >, 
std::allocator<std::pair<const std::__cxx11::basic_string<char>, unsigned 
int> > >::iterator {aka std::__detail::_Node_iterator<std::pair<const 
std::__cxx11::basic_string<char>, unsigned int>, false, true>}’
      return iterator( mTable->begin());
             ^~~~~~~~~~~~~~~~~~~~~~~~~~

0 个答案:

没有答案