2017-07-03 4 views
1

lower_boundには、Boost MultiIndex Containerのvalue_typeを使用したいと思います。これまでメンバーを明示的に抽出するだけで、この作業を行うことができました。boost numindex:lower_bound with value_type with argument

#include <boost/multi_index_container.hpp> 
#include <boost/multi_index/ordered_index.hpp> 
#include <boost/multi_index/composite_key.hpp> 
#include <boost/multi_index/member.hpp> 
#include <string> 

struct name { 
    std::string firstname; 
    std::string lastname; 
    name(const std::string & firstname, const std::string & lastname) : 
     firstname(firstname), lastname(lastname) {} 
}; 

typedef boost::multi_index::multi_index_container< 
    name, 
    boost::multi_index::indexed_by< 
     boost::multi_index::ordered_unique< 
      boost::multi_index::composite_key< 
       name, 
       boost::multi_index::member<name, std::string, &name::lastname>, 
       boost::multi_index::member<name, std::string, &name::firstname> 
      >, 
      boost::multi_index::composite_key_compare< 
       std::less<std::string>, 
       std::less<std::string> 
      > 
     > 
    > 
> NameIndex; 

int main(void) { 
    NameIndex nameindex; 
    nameindex.insert(name("Alfred", "Ammer")); 
    nameindex.insert(name("Martin", "Mauser")); 
    // In my real code, I get this object passed. 
    name lookupname("Hans", "Hoffer"); 

    // Does not compile 
    //auto it = nameindex.get<0>().lower_bound(lookupname); 

    // compiles, but I have to take explicitly list the members - in the right order 
    auto it = nameindex.get<0>().lower_bound(std::make_tuple(lookupname.lastname, lookupname.firstname)); 
} 

メンバの抽出を避けるにはどうすればよいですか?

答えて

2

は本当に問題を解決していません

auto it = nameindex.get<0>().lower_bound(
    nameindex.get<0>().key_extractor()(lookupname)); 
0

次のことを試してみてください。

Live On Coliru

#include <boost/multi_index_container.hpp> 
#include <boost/multi_index/ordered_index.hpp> 
#include <boost/multi_index/composite_key.hpp> 
#include <boost/multi_index/member.hpp> 
#include <string> 

struct name { 
    std::string firstname; 
    std::string lastname; 
    name(const std::string & firstname, const std::string & lastname) : 
     firstname(firstname), lastname(lastname) {} 
}; 

struct name_compare: 
    boost::multi_index::composite_key_compare< 
     std::less<std::string>, 
     std::less<std::string> 
    > 
{ 
    using base=boost::multi_index::composite_key_compare< 
     std::less<std::string>, 
     std::less<std::string> 
    >; 

    using base::operator(); 

    template<typename T> 
    bool operator()(const T& x,const name& y)const 
    { 
     return base::operator()(
      x, 
      std::make_tuple(std::ref(y.firstname),std::ref(y.lastname))); 
    } 

    template<typename T> 
    bool operator()(const name& x,const T& y)const 
    { 
     return base::operator()(
      std::make_tuple(std::ref(x.firstname),std::ref(x.lastname)), 
      y); 
    } 
}; 

typedef boost::multi_index::multi_index_container< 
    name, 
    boost::multi_index::indexed_by< 
     boost::multi_index::ordered_unique< 
      boost::multi_index::composite_key< 
       name, 
       boost::multi_index::member<name, std::string, &name::lastname>, 
       boost::multi_index::member<name, std::string, &name::firstname> 
      >, 
      name_compare 
     > 
    > 
> NameIndex; 

int main(void) { 
    NameIndex nameindex; 
    nameindex.insert(name("Alfred", "Ammer")); 
    nameindex.insert(name("Martin", "Mauser")); 
    // In my real code, I get this object passed. 
    name lookupname("Hans", "Hoffer"); 

    auto it = nameindex.get<0>().lower_bound(lookupname); 

    // this also works, as before 

    it = nameindex.get<0>().lower_bound(std::make_tuple(lookupname.lastname, lookupname.firstname)); 
} 
+0

を書きます。私は 'name'オブジェクトでlower_boundを使うことができますが、私はまだいくつかのヘルパーコードで合成キーの順序を反映させる必要があります。実際には、と定義していますが、順序はと仮定しているため、これは危険である可能性があります。 multi_index :: composite_keyで定義されている順序を使用することは本当に不可能ですか? –

+1

あなたが何を意味するかわかりました。私の他の答えを見てください。 –