Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

C++でzip (未完成)

C++で,複数の列からそれら各要素の同一インデックス同士の組を要素に持つ列を構成するzipを作ってみる.
手元の環境の制約からC++14上の実装を考えます.
もちろん,C++11でも,もっと新しい規格でもよいのですが…

とりあえず,まず始めに作成したコードはこれ1,2です.まだ未完成です.
コピーするのが面倒なので,リンクを貼るだけにします.

目標

まず,引数を可変長にしたいですね.

それと,できるだけコピーや一時的なオブジェクトの生成を減らしたいです.
多くの場合,zipの結果を使用する場面は,演算のフローが明確な場合が多いと思います.
簡単な例を挙げると,

for (auto&& t : zip(xs, ys, zs)) {
    const auto& x = std::get<0>(t);
    const auto& y = std::get<1>(t);
    auto& z = std::get<2>(t);
    z = f(x, y);
}

こんな感じかと思います.

作成コードには,参照方法が異なる3つのパターンを作成しました.
名前空間lrefは,左辺値参照で列を受け取ります.
zip内では,std::tieを使用して左辺値参照型を要素に持つstd::tuple型が要素のstd::vectorを作ります.

このzipは右辺値参照を取ることができません.
そのため,

auto a = zip(xs, zip(ys, zs));

こういったネストするような呼び出しのコードは書けません.
次のような書き方はOKです.

auto b = zip(ys, zs);
auto a = zip(xs, b);

今のところネスト呼び出しの必要性はありません.

そのため,引数の個数を可変長にする事を優先しようと思いますが…
どうやってパックしたり展開すればよいのか,すぐに思い付きません…

TODO

  1. 引数を可変長にする.
  2. できるだけコピーや一時オブジェクトの数を減らす.
  3. 右辺値参照を受け取れるようにする.

引数を可変長にするには,std::tupleの各要素に対してoperator*operator++を呼び,かつ返り値のstd::tupleで補足して返す関数があれば良さそう.
でも,どうやって定義するんだ?

また,色々書いてみた2が,この実装はコンパイルは通るが実行時エラーになってしまう…

コンパイル時zip

zipの対象となる列が全てstd::arrayならば,constexpr関数として定義できるそうだ3

つまり,それ以外,例えばstd::vectorを使用する限り,やはり,何らかのコピーや一時オブジェクトの生成は避けられないという事なのかもしれない.

参考情報

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
0
Help us understand the problem. What are the problem?