std::transform では1つのコンテナに対して所謂 map の操作を行えたり,2つのコンテナに対して所謂 zipWith を行えます.
今回は C++11 で新たに導入された Variadic Templates を使って,対象となるコンテナの数を任意個になるように拡張してみました.
template< class Func, class OutputIter, class InputIter, class... InputIters > OutputIter zip_with( InputIter first1, InputIter last1, OutputIter d_first, Func const& func, InputIters... rest_iters ) { for( auto from=first1; from!=last1; ++from ){ *d_first++ = func( *from, (*rest_iters++)... ); } return d_first; }
引数の順序が std::transform と違いますが,これは可変長引数の制約があるためです.
パラメータパックを ... で展開した時に,ついでに後置++を適用することで,すべてのイテレータを1つずつ前に進めます.
こんな感じで使えます.
int main() { std::vector<int> vec1 = {1, 2, 3, 4}; std::vector<int> vec2 = {10, 20, 30, 40}; std::vector<int> vec3 = {100, 200, 300, 400}; std::vector<int> vec4 = {1000, 2000, 3000, 4000}; std::vector<int> result(4); zip_with( std::begin(vec1), std::end(vec1), std::begin(result), [](int a, int b, int c, int d){ return a+b+c+d; }, std::begin(vec2), std::begin(vec3), std::begin(vec4) ); // result == {1111, 2222, 3333, 4444} return 0; }
vec1 から vec4 までのコンテナの各要素をすべて足し合わせています.