変数テンプレートを使った時、コンパイラのバグに遭遇したので記載する。エラーに遭遇した時のコードとは別のコードを書き下ろしている。
// 変数テンプレートを持つクラス
struct Foo {
template <typename Tp>
static constexpr Tp var{0};
};
// それを持つクラステンプレートを定義し、
template <typename VTp, typename T>
struct Bar {
static constexpr auto Var = VTp::template var<T>;
};
int main(int argc __attribute__((unused)),
char *argv[] __attribute__((unused))) {
// インスタンス化する
int x = Bar<Foo, int>::Var;
return 0;
}
これを g++ でコンパイルしてみた。(行番号は上のコードとは対応してません)
templ_var.cc: In instantiation of ‘constexpr const auto Bar<Foo, int>::Var’:
templ_var.cc:10:25: required from ‘struct Bar<Foo, int>’
templ_var.cc:15:24: required from here
templ_var.cc:10:25: error: ‘template<class Tp> constexpr const Tp Foo::var<Tp>’ is not a function template
static constexpr auto Var = VTp::template var<T>;
^
templ_var.cc:10:25: error: ‘var<T>’ is not a member of ‘Foo’
文法的には正しいハズなんだがなと思いつつも g++ はエラーを報告してくる。それにしても "is not a function template" って云うてるけどこれ関数ちゃうし、と思って、clang 3.7 で試してみるとコンパイルは通って、想定した結果が得られた。 Stackoverflow でも同様の話題が投稿されており、このスレッドのコメントで g++, clang プロジェクト宛のバグレポートもあげられているようだ。 clang では最近修正されたが、g++5.0.2 の現時点では修正される気配は無い模様。
g++ でも動くようにするには、変数テンプレートを使う方で、内部クラスを作ってその中で使えばエラーは回避できるようだ。詳しくは上のスレッドに投稿されているレスで。