SFINAEの実装バグ?
以前書いた自作ライブラリの1ツールは1週間程前にほぼ完成していたのですが、仕上げに取りかかったところ思わぬ問題に当たりました。
メタ関数クラスにおいて特定の状況でSFINAE(Substitution Failure Is Not An Error)が上手く働きません。おそらくコンパイラのバグではないかと思います。とりあえず一例を報告しておきます。
template< typename T1, typename T2 > struct meta_function_class{ template< typename U, class=void > struct apply{ static const bool value = true; }; template< typename T > struct apply< T, typename T::type<T1, T2>::type //C1001致命的なコンパイルエラー(*1) >{ static const bool value = false; }; }; struct for_test{ template< typename T1, typename T2 > struct apply{ typedef void type; }; }; /.../ //typedef meta_function_class< void, void >::apply< for_test > test_type; //ここまでならエラーにならない。 const bool f = meta_function_class< void, void >::apply< for_test >::value; //C1001(*2)
まぁ、これが作成しているツールの実装の全てですが…
それは置いておいて、見ての通り定義上は問題無いのですがいざ、問題の実装にアクセスしようとすると致命的なコンパイルエラーが発生します(*2)。しかしながら(*1)の行でT2を使用せずT1のみを使用した場合、問題は起きません。さらには例えばこのメタ関数クラスがT3以降のテンプレート引数を持っていた場合、T3以降を使用した場合でも同様の現象が起きます。
T1が使えてT2以降が使えないというのは道理に合わないのでコンパイラのバグじゃないかと思いますが、他の環境ではどうなんでしょうか…
とりあえずこの問題については間接化によって解決されそうなのでそちらに逃げることにします。