Алгоритмы STL довольно полезны в C ++. Но что меня раздражает, так это то, что им, похоже, не хватает сочетаемости.
Например, допустим, у меня есть vector<pair<int, int>>
и я хочу преобразовать его в vector<int>
, содержащий только second
член пары. Это достаточно просто:
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; });
Или, может быть, я хочу отфильтровать vector
только для тех пар, у которых first
член четный. Также довольно просто:
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
требуется выделение временного vector
для хранения промежуточного результата:
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 в новый, не требуя временного хранения?