highlight

2016年3月21日月曜日

変数テンプレートでコンパイラのバグに遭遇した

変数テンプレートを使った時、コンパイラのバグに遭遇したので記載する。エラーに遭遇した時のコードとは別のコードを書き下ろしている。


// 変数テンプレートを持つクラス
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++ でも動くようにするには、変数テンプレートを使う方で、内部クラスを作ってその中で使えばエラーは回避できるようだ。詳しくは上のスレッドに投稿されているレスで。

0 件のコメント:

コメントを投稿

スパムフィルタが機能しないようなので、コメント不可にしました。

注: コメントを投稿できるのは、このブログのメンバーだけです。