title: no viable conversion from returned value of type const_iterator to iterator
body: <p>Inspired by <a href="https://www.manning.com/books/c-plus-plus-concurrency-in-action" rel="noreferrer">Antony's Williams "C++ Concurrency in Action"</a> I wanted to take a closed look at his thread safe hash map. I copied its code and added some output operators and this is what I came up with:</p>
  
  <pre><code>#include &lt;boost/thread/shared_mutex.hpp&gt;
  #include &lt;functional&gt;
  #include &lt;list&gt;
  #include &lt;mutex&gt;
  #include &lt;iostream&gt;
  
  template &lt;typename Key, typename Value, typename Hash = std::hash&lt;Key&gt;&gt;
  class thread_safe_hashmap
  {
  private:
    class bucket_type
    {
    public:
      typedef std::pair&lt;Key, Value&gt; bucket_value;
      typedef std::list&lt;bucket_value&gt; bucket_data;
      typedef typename bucket_data::iterator bucket_iterator;
  
      bucket_data data;
      mutable boost::shared_mutex mutex;
  
      bucket_iterator find_entry_for(const Key&amp; key) const
      {
        return std::find_if(data.begin(), data.end(),
                            [&amp;](const bucket_value&amp; item) { return item.first == key; });
      }
  
    public:
      void add_or_update_mapping(Key const&amp; key, Value const&amp; value)
      {
        std::unique_lock&lt;boost::shared_mutex&gt; 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-&gt;second = value;
        }
      }
    };
  
    std::vector&lt;std::unique_ptr&lt;bucket_type&gt;&gt; buckets;
    Hash hasher;
  
    bucket_type&amp; get_bucket(Key const&amp; key) const
    {
      std::size_t const bucket_index = hasher(key) % buckets.size();
      return *buckets[bucket_index];
    }
  
    template &lt;typename Key2, typename Value2&gt;
    friend std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, const thread_safe_hashmap&lt;Key2, Value2&gt;&amp; map);
  
  public:
    thread_safe_hashmap(unsigned num_buckets = 19, Hash const&amp; hasher_ = Hash())
        : buckets(num_buckets), hasher(hasher_)
    {
      for (unsigned i = 0; i &lt; num_buckets; ++i)
      {
        buckets[i].reset(new bucket_type);
      }
    }
  
    thread_safe_hashmap(thread_safe_hashmap const&amp; other) = delete;
    thread_safe_hashmap&amp; operator=(thread_safe_hashmap const&amp; other) = delete;
  
    void add_or_update_mapping(Key const&amp; key, Value const&amp; value)
    {
      get_bucket(key).add_or_update_mapping(key, value);
    }
  };
  
  template &lt;typename First, typename Second&gt;
  std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, const std::pair&lt;First, Second&gt;&amp; p)
  {
    os &lt;&lt; p.first &lt;&lt; ' ' &lt;&lt; p.second &lt;&lt; '\n';
    return os;
  }
  
  template &lt;typename Key, typename Value&gt;
  std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, const thread_safe_hashmap&lt;Key, Value&gt;&amp; map)
  {
    for (unsigned i = 0; i &lt; map.buckets.size(); ++i)
    {
      for (const auto el : map.buckets[i]-&gt;data) os &lt;&lt; el &lt;&lt; ' ';
      os &lt;&lt; '\n';
    }
  
    return os;
  }
  
  
  int main()
  {
    thread_safe_hashmap&lt;std::string, std::string&gt; map;
    map.add_or_update_mapping("key1", "value1");  // problematic line
    std::cout &lt;&lt; map;
  }
  </code></pre>
  
  <p>The marked line is causing problems on both gcc and clang:</p>
  
  <pre><code>clang++  -Wall -std=c++14 main2.cpp -lboost_system -o main
  main2.cpp:24:14: error: no viable conversion from returned value of type 'std::_List_const_iterator&lt;std::pair&lt;std::__cxx11::basic_string&lt;char&gt;, std::__cxx11::basic_string&lt;char&gt; &gt; &gt;' to function
        return type 'bucket_iterator' (aka '_List_iterator&lt;std::pair&lt;std::__cxx11::basic_string&lt;char&gt;, std::__cxx11::basic_string&lt;char&gt; &gt; &gt;')
        return std::find_if(data.begin(), data.end(),
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  main2.cpp:32:37: note: in instantiation of member function 'thread_safe_hashmap&lt;std::__cxx11::basic_string&lt;char&gt;, std::__cxx11::basic_string&lt;char&gt;, std::hash&lt;string&gt; &gt;::bucket_type::find_entry_for'
        requested here
        bucket_iterator found_entry = find_entry_for(key);
                                      ^
  main2.cpp:71:21: note: in instantiation of member function 'thread_safe_hashmap&lt;std::__cxx11::basic_string&lt;char&gt;, std::__cxx11::basic_string&lt;char&gt;, std::hash&lt;string&gt;
        &gt;::bucket_type::add_or_update_mapping' requested here
      get_bucket(key).add_or_update_mapping(key, value);
                      ^
  main2.cpp:98:7: note: in instantiation of member function 'thread_safe_hashmap&lt;std::__cxx11::basic_string&lt;char&gt;, std::__cxx11::basic_string&lt;char&gt;, std::hash&lt;string&gt; &gt;::add_or_update_mapping'
        requested here
    map.add_or_update_mapping("key1", "value1");
        ^
  /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/c++/5.3.1/bits/stl_list.h:125:12: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from
        'std::_List_const_iterator&lt;std::pair&lt;std::__cxx11::basic_string&lt;char&gt;, std::__cxx11::basic_string&lt;char&gt; &gt; &gt;' to 'const std::_List_iterator&lt;std::pair&lt;std::__cxx11::basic_string&lt;char&gt;,
        std::__cxx11::basic_string&lt;char&gt; &gt; &gt; &amp;' for 1st argument
      struct _List_iterator
             ^
  /usr/bin/../lib/gcc/x86_64-linux-gnu/5.3.1/../../../../include/c++/5.3.1/bits/stl_list.h:125:12: note: candidate constructor (the implicit move constructor) not viable: no known conversion from
        'std::_List_const_iterator&lt;std::pair&lt;std::__cxx11::basic_string&lt;char&gt;, std::__cxx11::basic_string&lt;char&gt; &gt; &gt;' to 'std::_List_iterator&lt;std::pair&lt;std::__cxx11::basic_string&lt;char&gt;,
        std::__cxx11::basic_string&lt;char&gt; &gt; &gt; &amp;&amp;' for 1st argument
  1 error generated.
  </code></pre>
  
  <p><a href="http://melpon.org/wandbox/permlink/LmpyxGKs4qPPWkwm" rel="noreferrer">melpon's online demo</a></p>
  
  <p>What am I missing here?</p>