2016-05-06 13 views
0

Ich habe einen boost :: multi_index Container. Könnte mir jemand sagen, wie man eine Reihe von Iteratoren basierend auf einem bestimmten Schlüssel abruft? Nach stundenlanger Suche bekam ich die Idee, dass lower_bound oder outer_bound den Trick machen sollte, aber ich habe immer noch kein Beispiel. Im folgenden Beispiel möchte ich alle Iteratoren mit einem Preis zwischen 22 und 24 erhalten. Vielen Dank.Wie findet man alle Treffer boost :: multi_index mit einem Schlüssel?

struct order              
{                 
    unsigned int id;           
    unsigned int quantity;          
    double   price;           

    order(unsigned int id_, unsigned int quantity_, double price_) 
     :id(id_), quantity(quantity_), price(price_){} 
} 
typedef multi_index_container<          
    order,               
    indexed_by<              
    ordered_unique<            
     tag<id>, BOOST_MULTI_INDEX_MEMBER(order, unsigned int, id), 
     std::greater<unsigned int>>,         
    ordered_non_unique<           
     tag<price>,BOOST_MULTI_INDEX_MEMBER(order ,double, price)> 
    >                
> order_multi;                
int main()                
{                  
    order_multi order_book;           

    order_book.insert(order(/*id=*/0, /*quantity=*/10, /*price=*/20)); 
    order_book.insert(order(/*id=*/1, /*quantity=*/11, /*price=*/21)); 
    order_book.insert(order(/*id=*/3, /*quantity=*/12, /*price=*/22)); 
    order_book.insert(order(/*id=*/2, /*quantity=*/1, /*price=*/22)); 
    order_book.insert(order(/*id=*/4, /*quantity=*/1, /*price=*/23)); 
    order_book.insert(order(/*id=*/5, /*quantity=*/1, /*price=*/24)); 
    order_book.insert(order(/*id=*/6, /*quantity=*/1, /*price=*/24)); 
    order_book.insert(order(/*id=*/7, /*quantity=*/1, /*price=*/26)); 

    }                                 

Antwort

1

Der Bereich sind Sie nach ist [lower_bound(22), upper_bound(24)), das heißt:

auto first=order_book.get<price>().lower_bound(22); 
auto last=order_book.get<price>().upper_bound(24); 
for(;first!=last;++first)std::cout<<first->id<<" "; // prints 3 2 4 5 6 

Wenn Sie es verwirrend bestimmen finden, wenn es lower_ oder upper_bound ist, die Sie verwenden müssen, gibt es ein range member function, die wahrscheinlich leichter zu bekommen richtig ist (und schneller marginal):

auto range=order_book.get<price>().range(
    [](double p){return p>=22;}, // "left" condition 
    [](double p){return p<=24;}); // "right" condition 
for(;range.first!=range.second;++range.first)std::cout<<range.first->id<<" "; 

vorausgesetzt, Sie verwenden C++ 11 und haben Lambda-Funktionen. Sie können auch range in C++ 03 ohne native Lambda-Funktionen verwenden, aber dann müssen Sie auf Boost.Lambda zurückgreifen oder die von range akzeptierten Funktoren manuell schreiben, wobei beide Optionen wahrscheinlich zu umständlich sind.

+0

Kühl. TIL über die 'range()' -Mitgliedsfunktion. Wie konnte ich es so lange verpasst haben? Ich würde übrigens 'for (auto & el: boost :: make_iterator_range (order_book.get () .range (...))) {...} verwenden – sehe

Verwandte Themen