テンプレートの特殊化(Rust版)

はじめに

 既存のC++プログラムをRustを用いて書き換えている(仕事ではなく)。このプログラムはテンプレートを多用しているため、Rustにおけるテンプレート代替機能であるgenericsを利用することになる。C++にはテンプレートの特殊化と呼ばれる機能があるが、Rustにはそれに相当する機能がない。どのようにすれば、当該機能を実現できるのか調べたので紹介したい。
 Rustが特殊化をサポートしない理由はあるだろうし(もしかしてこれからサポートするのかしら)、C++の思想のままRustで実装するべきでないという主張はもっともだと思う。今回は、ひとつの余興である。

C++におけるtemplateの特殊化

 まず最初にC++のtemplate特殊化の典型例を以下に示す(ファイル名:point.h)。

これを使う側のmain.cppの実装は以下の通り。

template特殊化とは、具体的なtemplate引数を与えた場合の中身を個別に定義する仕組みである。上の例の場合、次元数を表すtemplate引数Dについて、これが2の場合と3の場合を定義している(Dが4の場合は構造体は未定義となりコンパイルエラーになる)。同じことをRustでもしたい。

Rustの場合

 Rustの場合、templateに相当する機能はgenericsである。genericsは特殊化をサポートしないが、後述する仕組みを使うと以下の呼び出し側のコードを実現できる。

newはC++のコンストラクタに相当する関数である。

種明かし

 まず最初に2次元の場合の構造体と3次元の場合の構造体を定義し、それぞれについてnew関数を定義する。

次元の振り分けを行うため次を定義する。

そして、2つの構造体TwoDimThreeDimのそれぞれに対しTypeの中身を実装する。

最後に次を定義すれば完成する。

 今回の全コードはここにある。

まとめ

 どうやるんだろうとネットを漁っていたところ、上の回答を見つけた(少し変更してある)。なるほど。RustのgenericsはC++のtemplate以上に引数に課される条件が厳しく、しばしば身動きできなくなる。まだまだ修行が足りない(笑)。

参照文献

Generics partial specialization in Rust

Kumada Seiya

Kumada Seiya

仕事であろうとなかろうと勉強し続ける、その結果”中身”を知ったエンジニアになれる

最近の記事

  • 関連記事
  • おすすめ記事
  • 特集記事

アーカイブ

カテゴリー

PAGE TOP