title: C++ Index ordering issue with Boost MultiIndex as an LRU cache
body: <p>I have the following LRU implementation made using Boost.MultiIndex bashed on this <a href="http://www.boost.org/doc/libs/1_51_0/libs/multi_index/example/serialization.cpp" rel="nofollow">example</a>.</p>
  
  <p>The problem is when I change the ordering of the index_by section (and update the enum index_idx accordingly) I get an error on the line that contains:</p>
  
  <pre><code>cache_.insert(ci);
  </code></pre>
  
  <p>With the following diagnostic:</p>
  
  <blockquote>
    <p>Error 1  error C2661:
    'boost::multi_index::detail::sequenced_index::insert'
    : no overloaded function takes 1 arguments c:\code\code.cpp 79</p>
  </blockquote>
  
  <p>The code is as follows:</p>
  
  <pre><code>#include &lt;boost/multi_index_container.hpp&gt;
  #include &lt;boost/multi_index/tag.hpp&gt;
  #include &lt;boost/multi_index/member.hpp&gt;
  #include &lt;boost/multi_index/hashed_index.hpp&gt;
  #include &lt;boost/multi_index/sequenced_index.hpp&gt;
  
  using namespace boost::multi_index;
  
  template &lt;typename Key, typename T&gt;
  class lru_cache
  {
  private:
  
     struct item_t
     {
        Key key;
        T   t;
     };
  
     typedef boost::multi_index_container
     &lt;
        item_t,
        boost::multi_index::indexed_by
        &lt;
           hashed_unique&lt;boost::multi_index::member&lt;item_t,Key,&amp;item_t::key&gt; &gt;,
           sequenced&lt;&gt;
        &gt;
     &gt; cache_t;
  
     enum index_idx
     {
        e_map = 0,
        e_seq = 1,
     };
  
     cache_t cache_;
     size_t max_cache_size_;
  
  public:
  
     typedef typename std::pair&lt;Key,T&gt; item_pair_t;
  
     lru_cache(size_t max_cache_size = 1)
     : max_cache_size_(max_cache_size)
     {}
  
     bool find(const Key&amp; key, T&amp; t)
     {
        typename cache_t::nth_index&lt;e_map&gt;::type&amp; hash_index = cache_.get&lt;e_map&gt;();
        auto itr = hash_index.find(key);
        if (itr != hash_index.end())
        {
           return false;
        }
        t = itr-&gt;t;
        typename cache_t::nth_index&lt;e_seq&gt;::type&amp; sequenced_index = cache_.get&lt;e_seq&gt;();
        auto itr2 = cache_.project&lt;e_seq&gt;(itr);
        sequenced_index.relocate(itr2,sequenced_index.end());
        return true;
     }
  
     void insert(const Key&amp; key, const T&amp; t)
     {
        if (cache_.size() &gt;= max_cache_size_)
        {
           typename cache_t::nth_index&lt;e_seq&gt;::type&amp; sequenced_index = cache_.get&lt;e_seq&gt;();
           sequenced_index.erase(sequenced_index.begin());
        }
        typename cache_t::nth_index&lt;e_map&gt;::type&amp; hash_index = cache_.get&lt;e_map&gt;();
        auto itr = hash_index.find(key);
        item_t ci = {key,t};
        if (itr == hash_index.end())
           cache_.insert(ci);  // &lt;--- Error here....
        else
           hash_index.replace(itr,ci);
     }
  };
  
  int main()
  {
     typedef lru_cache&lt;int,int&gt; lru_cache_t;
     lru_cache_t lc(2);
     lc.insert(1,1);
     int v;
     lc.find(1,v);
     return 0;
  }
  </code></pre>
  
  <p>Modified index ordering:</p>
  
  <pre><code>   typedef boost::multi_index_container
     &lt;
        item_t,
        boost::multi_index::indexed_by
        &lt;
           sequenced&lt;&gt;,
           hashed_unique&lt;boost::multi_index::member&lt;item_t,Key,&amp;item_t::key&gt; &gt;
        &gt;
     &gt; cache_t;
  
     enum index_idx
     {
        e_map = 1,
        e_seq = 0,
     };
  </code></pre>