2016-07-27 2 views
1

Предположим, у меня есть контейнер STL с std :: pair. Есть ли способ адаптировать второй пара для алгоритма STL лямбда, используя boost?Adapt std :: пара для алгоритма STL lambda

std::vector<std::pair<int, SomeStruct>> vec; 
const auto Predicate = [](SomeStruct const& s) { ... }; 
auto it = std::find_if(vec.begin(), vec.end(), boost-magic(Predicate)); 

ответ

2

Используя заголовки boost/range/algorithm/find_if.hpp и boost/range/adaptor/transformed.hpp вы можете использовать:

auto it = boost::find_if(vec | boost::adaptors::transformed(
    [](std::pair<int, SomeStruct>& p){ return p.second; }),Predicate); 

Я не знаю, о чем-то короче, чем [](std::pair<int, MyClass>& p){ return p.second; }. Необработанный std::get<1> не работает в этом контексте, поскольку он не является функтором. Но мой C++ 14-компилятор также принял выражение [](auto& p){ return std::get<1>(p); } или [](auto& p){ return p.second; }

Update: Вы можете использовать boost::phoenix::at_c<0>(boost::phoenix::arg_names::arg1) для получения доступа к функции first члена пары и boost::lambda::bind(Predicate,boost::lambda::_1) сделать Predicate работать вместе с этой функцией и повышением :: разделители-оператор Lambda в перегружать объединить оба:

auto it = boost::find_if(vec, (boost::lambda::bind(Predicate,boost::lambda::_1),boost::phoenix::at_c<0>(boost::phoenix::arg_names::arg1)));  

Но я бы не назвал это «повышение магии», это больше похоже на создание вещей ненужную комплекса.

+0

Я видел нечто подобное с std :: vector с использованием boost :: arg1. Я действительно не знаю, как работает arg1, но мне было интересно, можно ли его использовать для адаптации std :: pair. – JobNick

6

Не нужно повышать. Вы можете просто написать лямбда, или именованный объект функции:

const auto Predicate2 = [&Predicate](std::pair<int, SomeStruct> const& s) { 
    return Predicate(s.second); 
}; 
auto it = std::find_if(vec.begin(), vec.end(), Predicate2); 

Конечно, если Predicate только когда-либо использовали в этом одном случае, то это имело бы больше смысла писать это принять пару напрямую.

Смежные вопросы