次のような機能を満す関数zip
を作ってほしい。ただし次のような制約がある。
- C++11
- STLはOK
- BoostはNG
template<int N, typename... T>
auto zip(const std::array<T, N>&... containers) -> decltype(std::make_tuple(std::begin(containers)...))
C++はよく分からないので間違ってるかも……。 →間違っているようですので、ニュアンスだけ提供します。
実装してくださった方々のコードによると、次のようなものが正しいようです。
template<int N, typename... T>
auto zip(const std::array<T, N>&... containers) -> std::array < std::tuple < T ... > , N >
まあ、正直この辺は適当でいいです。
std::array<int, 5> a = {1, 2, 3, 4, 5};
std::array<char, 5> b = {'a', 'b', 'c', 'd', 'e'};
zip<5>(a, b);
// -> std::array<std::tuple<int, char>, 5> : (1, 'a'); (2, 'b'); ...; (5, 'e')
std::array<int, 4> c = {1, 2, 3, 4};
zip<4>(a, c)
// -> compile time error
std::vector<int> d = {1, 2, 3, 4, 5}
zip<5>(a, d)
// -> complie time error
僕の考えでは、std::array
というのは型パラメータを2つ取り、それは
- 配列の要素の型(
T
) - 長さ(
N
)
という内訳になっていると思います。
ということは、この配列は単なるT
型の配列ではなくて、長さがN
で要素がT
型の配列という情報になっていると思います。
なので、このzip
関数は、このN
という長さの情報を使って、コンパイル時に長さが異なる配列が挿入されるとコンパイルエラーになるようにして欲しいです。
これは僕がzip
関数が使いたいというよりは、Boostを使わずに長さN
に依存したT
型の配列を使うと、こういう便利なこと(= 長さの違う配列がぶち込まれるとコンパイル時に死ぬ)が出来るという例として考えてみました。
BoostがNGなのは、中で何をやっているのか不明だからです。
長さなどの情報に依存した配列が使えるとこういう便利が〜という目的なので、オーダーとかは正直適当でいいと思います。
まずC++11ということですが、僕の手元の処理系が対応しているのが、たぶんC++11までだろうということで採用しました。 特に深い理由はなくコードのテストが出来そうだからというだけです。 どうやらWeb上で実行させる物体があるようなので、これはぶっちゃけどうでもよかったかもしれないです。
これはまあ書いておかないとダメなのかなーと思ったので書いただけです。
このような話が最近ありました。
やばい。いま作ってる科学技術計算の処理だと、ruby 36秒、perl 12秒、C++ 5秒、python 3.8秒だった。python以外でも書き方を変えれば劇的に高速化はするけれど、テクニックを用いず素直に書いてこれは大きい。科学計算でpythonがよく使われる訳が分かった。
これについて僕のタイムラインの中で、これはFORTRANで実装された物体を呼び出してるから早いのでは? みたいなツイートを多く目にしました。
これと今回の物体がどれほど関係あるのか微妙ですが、例えば「Rubyにはこの機能使えます(Pure Ruby)」と「Rubyにはこの機能が使えます(C拡張)」 では全然違うと思うので、とりあえず何をやってるのか謎なライブラリの使用は制限させてもらいました。
えりっく君の助け(煽り)により、様々な人が実装してくれました。ありがとうございます。
- https://twitter.com/PG_nonen/status/404885120135331841
- https://twitter.com/bolero_MURAKAMI/status/404886144526999552
- https://twitter.com/fimbul11/status/404903354658062336
- https://twitter.com/EzoeRyou/status/404900462802915328
- https://twitter.com/fadis_/status/404899136387837952
- https://twitter.com/sscrisk/status/405154223634907136
江添さんがテンプレートメタプログラミングを用いた技法を解説しています。
多くの方に実装していただき、特に@fimbul11さんにはテンプレートメタプログラミングについて様々な解説をしていただきました。ありがとうございます。
このzip
関数を実装するにあたり、このような超絶技巧を駆使する言語はC++だけなのではないでしょうか。つくづく舌を巻くばかりです。
@PG_nonenさんによって実装されたコードは唯一ランタイム関数です。 僕はこの10行で実装されたバージョンもとてもよいと思っています。確かに副作用とかランタイムとか色々見劣りするところはあると思いますが、 それでも10行で実装出来ているという事実は評価されるべきことだと思います。 他の言語の事はよく分かりませんが、恐らくコンパイル時に配列の長さをチェックするという芸当が出来るのは、それほど多くはないと思います。 そのようなリッチな要求をたった10行で実装出来る表現力は、評価されるべきなのではないかと思います。
このテンプレートメタプログラミングを駆使した超絶技巧をよしとするか、 あるいは簡潔な実装をよしとするか、人々に問う機会となればいいのではないでしょうか。