Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从const_iterator类型的返回值到iterator类型没有可行的转换_C++_Templates_C++11_Concurrency_C++14 - Fatal编程技术网

C++ 从const_iterator类型的返回值到iterator类型没有可行的转换

C++ 从const_iterator类型的返回值到iterator类型没有可行的转换,c++,templates,c++11,concurrency,c++14,C++,Templates,C++11,Concurrency,C++14,受此启发,我想仔细看看他的线程安全散列图。我复制了它的代码并添加了一些输出运算符,这就是我想到的: #include <boost/thread/shared_mutex.hpp> #include <functional> #include <list> #include <mutex> #include <iostream> template <typename Key, typename Value, typename H

受此启发,我想仔细看看他的线程安全散列图。我复制了它的代码并添加了一些输出运算符,这就是我想到的:

#include <boost/thread/shared_mutex.hpp>
#include <functional>
#include <list>
#include <mutex>
#include <iostream>

template <typename Key, typename Value, typename Hash = std::hash<Key>>
class thread_safe_hashmap
{
private:
  class bucket_type
  {
  public:
    typedef std::pair<Key, Value> bucket_value;
    typedef std::list<bucket_value> bucket_data;
    typedef typename bucket_data::iterator bucket_iterator;

    bucket_data data;
    mutable boost::shared_mutex mutex;

    bucket_iterator find_entry_for(const Key& key) const
    {
      return std::find_if(data.begin(), data.end(),
                          [&](const bucket_value& item) { return item.first == key; });
    }

  public:
    void add_or_update_mapping(Key const& key, Value const& value)
    {
      std::unique_lock<boost::shared_mutex> lock(mutex);
      bucket_iterator found_entry = find_entry_for(key);
      if (found_entry == data.end())
      {
        data.push_back(bucket_value(key, value));
      }
      else
      {
        found_entry->second = value;
      }
    }
  };

  std::vector<std::unique_ptr<bucket_type>> buckets;
  Hash hasher;

  bucket_type& get_bucket(Key const& key) const
  {
    std::size_t const bucket_index = hasher(key) % buckets.size();
    return *buckets[bucket_index];
  }

  template <typename Key2, typename Value2>
  friend std::ostream& operator<<(std::ostream& os, const thread_safe_hashmap<Key2, Value2>& map);

public:
  thread_safe_hashmap(unsigned num_buckets = 19, Hash const& hasher_ = Hash())
      : buckets(num_buckets), hasher(hasher_)
  {
    for (unsigned i = 0; i < num_buckets; ++i)
    {
      buckets[i].reset(new bucket_type);
    }
  }

  thread_safe_hashmap(thread_safe_hashmap const& other) = delete;
  thread_safe_hashmap& operator=(thread_safe_hashmap const& other) = delete;

  void add_or_update_mapping(Key const& key, Value const& value)
  {
    get_bucket(key).add_or_update_mapping(key, value);
  }
};

template <typename First, typename Second>
std::ostream& operator<<(std::ostream& os, const std::pair<First, Second>& p)
{
  os << p.first << ' ' << p.second << '\n';
  return os;
}

template <typename Key, typename Value>
std::ostream& operator<<(std::ostream& os, const thread_safe_hashmap<Key, Value>& map)
{
  for (unsigned i = 0; i < map.buckets.size(); ++i)
  {
    for (const auto el : map.buckets[i]->data) os << el << ' ';
    os << '\n';
  }

  return os;
}


int main()
{
  thread_safe_hashmap<std::string, std::string> map;
  map.add_or_update_mapping("key1", "value1");  // problematic line
  std::cout << map;
}
#包括
#包括
#包括
#包括
#包括
模板
类线程\u安全\u哈希映射
{
私人:
类bucket\u类型
{
公众:
typedef std::对bucket_值;
typedef std::列出bucket_数据;
typedef typename bucket_data::迭代器bucket_迭代器;
桶数据;
可变增强::共享互斥互斥;
bucket迭代器查找(const Key和Key)const的条目
{
返回std::find_if(data.begin(),data.end(),
[&](const bucket_value&item){return item.first==key;});
}
公众:
无效添加或更新映射(键常量和键、值常量和值)
{
std::唯一锁(互斥锁);
bucket_迭代器find_entry=find_entry_for(键);
if(found_entry==data.end())
{
数据。推回(桶值(键,值));
}
其他的
{
找到\u条目->秒=值;
}
}
};
std::向量桶;
散列哈希器;
桶类型和获取桶(键常量和键常量)
{
std::size_t const bucket_index=hasher(key)%bucket.size();
返回*桶[桶索引];
}
模板

friend std::ostream&operator这是预期的行为。在
中为
查找条目时,您试图返回
常量迭代器
,该迭代器与返回类型
迭代器
不匹配

find\u entry\u for
是常量成员函数,用于
data.begin()
数据将是
常量std::list
,调用它将返回
常量迭代器
。并将返回与参数迭代器类型相同的类型,即
常量迭代器
,不能隐式转换为
查找
的返回类型,即
桶迭代器
>(
std::list::iterator

因为返回的迭代器可能用于更改它指向的值,所以您可以

  • find\u entry\u更改为非常量成员函数。(或将其添加为新的重载函数,将原始常量成员函数的返回类型更改为
    const\u迭代器

  • 在返回之前,请尝试重新启动


  • bucket\u迭代器的定义如下

    typedef typename bucket_data::iterator bucket_iterator;
    
    也就是说,它不是一个常量迭代器

    但是,在成员函数
    中查找

    bucket_iterator find_entry_for(const Key& key) const
    {
      return std::find_if(data.begin(), data.end(),
                          [&](const bucket_value& item) { return item.first == key; });
    }
    
    标准算法
    std::find_if
    使用常量迭代器,因为此成员函数是用限定符
    const
    声明的,并且常量数据成员
    数据
    使用了重载函数
    begin
    end

    因此,您需要在类中定义常量迭代器,并将其用作函数的返回类型

    比如说

    typedef typename bucket_data::const_iterator const_bucket_iterator;
    

    修复方法是使该函数返回
    const\u迭代器
    。C++11使这些函数变得实际有用,如果您发现自己需要修改数据,您也可以添加非const重载……并为
    添加另一个
    find\u entry\u定义,而不使用
    const
    说明符来允许通过返回迭代器进行修改,对吗?顺便说一句,非常感谢您澄清,当我调用
    const
    方法I时,它将
    const
    方法本身。我错过了这一点。
    typedef typename bucket_data::const_iterator const_bucket_iterator;