Алгоритмы STL - довольно полезная вещь в C ++. Но меня раздражает то, что им не хватает возможности компоновки.
Например, допустим, у меня есть vector
и хотите преобразовать его в вектор
, содержащий только второй
член пары. Это достаточно просто:
std::vector<std::pair<int, int>> values = GetValues();
std::vector<int> result;
std::transform(values.begin(), values.end(), std::back_inserter(result),
[] (std::pair<int, int> p) { return p.second; });
Или, может быть, я хочу отфильтровать вектор
только для тех пар, у которых первый член
четный. Тоже довольно просто:
std::vector<std::pair<int, int>> values = GetValues();
std::vector<std::pair<int, int>> result;
std::copy_if(values.begin(), values.end(), std::back_inserter(result),
[] (std::pair<int, int> p) { return (p.first % 2) == 0; });
Но что, если я хочу сделать и то, и другое? Не существует алгоритма transform_if
, и использование обоих transform
и copy_if
, похоже, требует выделения временного вектора
для хранения промежуточного результата:
std::vector<std::pair<int, int>> values = GetValues();
std::vector<std::pair<int, int>> temp;
std::vector<int> result;
std::copy_if(values.begin(), values.end(), std::back_inserter(temp),
[] (std::pair<int, int> p) { return (p.first % 2) == 0; });
std::transform(values.begin(), values.end(), std::back_inserter(result),
[] (std::pair<int, int> p) { return p.second; });
Это кажется мне довольно расточительным. Единственный способ избежать временного вектора - отказаться от transform
и copy_if
и просто использовать for_each
(или обычный цикл for, в зависимости от того, что вам подходит фантазии):
std::vector<std::pair<int, int>> values = GetValues();
std::vector<int> result;
std::for_each(values.begin(), values.end(),
[&result] (std::pair<int, int> p)
{ if( (p.first % 2) == 0 ) result.push_back(p.second); });
Я что-то упустил? Есть ли хороший способ объединить два существующих алгоритма STL в новый без необходимости во временном хранилище?