6

SFINAE を使用して、クラスに特定の型を取るオーバーロードされたメンバー関数があるかどうかを検出しようとしています。私が持っているコードは、Visual Studio と GCC で正しく動作するようですが、Comeau オンライン コンパイラを使用してコンパイルしません。

私が使用しているコードは次のとおりです。

#include <stdio.h>

//Comeau doesnt' have boost, so define our own enable_if_c
template<bool value> struct enable_if_c { typedef void type; };
template<> struct enable_if_c< false > {}; 


//Class that has the overloaded member function
class TestClass
{
public:
    void Func(float value) { printf( "%f\n", value ); }
    void Func(int value) { printf( "%i\n", value ); }
};


//Struct to detect if TestClass has an overloaded member function for type T
template<typename T>
struct HasFunc
{
    template<typename U, void (TestClass::*)( U )> struct SFINAE {};
    template<typename U> static char Test(SFINAE<U, &TestClass::Func>*);
    template<typename U> static int Test(...);
    static const bool Has = sizeof(Test<T>(0)) == sizeof(char);
};


//Use enable_if_c to only allow the function call if TestClass has a valid overload for T
template<typename T> typename enable_if_c<HasFunc<T>::Has>::type CallFunc(TestClass &test, T value) { test.Func( value ); } 

int main()
{
    float value1 = 0.0f;
    int value2 = 0;
    TestClass testClass;
    CallFunc( testClass, value1 );  //Should call TestClass::Func( float )
    CallFunc( testClass, value2 );  //Should call TestClass::Func( int )
}

エラー メッセージは次のとおりです。関数テンプレート「CallFunc」のインスタンスが引数リストと一致しません。HasFunc::Has が true であるべき int と float に対して false のようです。

これは Comeau コンパイラのバグですか? 私は標準的ではないことをしていますか?もしそうなら、それを修正するために何をする必要がありますか?

アップデート

これがバグである場合、それを回避するために何かできることはありますか? &TestClass::Func で static_cast を使用しようとしましたが、それが不可能であるか、コンパイルできなかったため正しい構文を取得できませんでした。

それが解決策でない場合、問題を回避するために TestClass または HasFunc に変更を加えることはできますか?

4

1 に答える 1

0

問題は、TestClass が Func をオーバーロードし、Comeau コンパイラが &TestClass::Func を明確にすることができないことだと思います。

于 2010-05-04T20:01:40.903 に答える