Составность алгоритмов STL

Алгоритмы 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 в новый без необходимости во временном хранилище?

38
задан Sven 19 July 2011 в 08:26
поделиться