C++14(17) で zip 書いてみた
現状の C++ で zip を書いたらどうなるんだろう、と思って書いてみました。
[コード]
#include <iostream> #include <algorithm> #include <vector> #include <tuple> template<typename T, typename U> constexpr auto zip_impl(T v1, U v2){ auto vi1 = std::begin(v1); auto vi2 = std::begin(v2); using value_t = decltype(std::make_tuple(*vi1, *vi2)); std::vector<value_t> result{}; while(vi1 != std::end(v1) && vi2 != std::end(v2)){ result.emplace_back(*vi1, *vi2); vi1++; vi2++; } return result; } template<typename T, typename U> constexpr auto zip(T v1, U v2){ return zip_impl(v1, v2); } template<typename T, typename U> constexpr auto zip(std::initializer_list<T> v1, std::initializer_list<U> v2){ return zip_impl(v1, v2); } int main(){ for(auto [x, y] : zip({1, 2, 3, 4, 5}, {'a', 'b', 'c', 'd', 'e'})){ std::cout << x << ":" << y << std::endl; } return 0; }
[出力]
1:a 2:b 3:c 4:d 5:e
https://wandbox.org/permlink/qQEvmwNMjgVt3GHJ
手癖で constexpr
をつけているけど特に constexpr
ではない(std::vector
に依存してるので constexpr
には出来ない…。
使う側では C++17 の『構造化束縛』を使っているけど、実装側は C++14 でも動作すると思う。
っていうか、range based-for で構造化束縛使うのかなり強力なのではないだろうか???
実装は単純に2つのコンテナを iterator で回しながらタプルで保持するようにしてるだけですね。
特に複雑なことはしていないと思う。
最適解かどうかは別としてこういうコードが C++ でも雑に書けるようになったのはだいぶよさがあるなあ。