5

コードのデバッグにかなりの時間を費やした後、enable_ifを使用して、問題の理由を予期しないテンプレートの特殊化の結果まで追跡しました。

次のコードは、Visual Studio 2010(および2008)のDoTest()でのアサーションに失敗しますが、g++3.4.5では失敗しません。ただし、SomeClassからテンプレートを削除するか、 my_conditionをSomeClassのスコープ外に移動すると、MSVCでも機能します。

この動作を(少なくとも部分的に)説明するこのコードに何か問題がありますか、それともこれはMSVCコンパイラのバグですか?

(このサンプルコードを使用すると、boostとc ++ 0x stlバージョンで同じです)

#include <cassert>
#include <boost\utility\enable_if.hpp>

template <class X>
class SomeClass {
public:
    template <class T>
    struct my_condition {
        static const bool value = true;
    };

    template <class T, class Enable = void> 
    struct enable_if_tester { 
        bool operator()() { return false; }
    };

    template <class T>
    struct enable_if_tester<T, typename boost::enable_if< my_condition<T> >::type> { 
        bool operator()() { return true; }
    };

    template <class T>
    void DoTest() {
        enable_if_tester<T> test;
        assert( test() );
    }
};

int main() {
    SomeClass<float>().DoTest<int>();
    return 0;
}

条件をスコープ外に移動して修正しようとすると、std :: enable_ifを使用する場合でもこれでは不十分であることに気付きましたが、少なくともboost :: enable_if:で機能します。

#include <cassert>
//#include <boost\utility\enable_if.hpp>
#include <type_traits>

template <class T, class X>
struct my_condition {
    static const bool value = true;
};

template <class X>
class SomeClass {
public:
    template <class T, class Enable = void> 
    struct enable_if_tester { 
        bool operator()() { return false; }
    };

    template <class T>
    //struct enable_if_tester<T, typename boost::enable_if< my_condition<T, X> >::type> { 
    struct enable_if_tester<T, typename std::enable_if< my_condition<T, X>::value >::type> { 
        bool operator()() { return true; }
    };

    template <class T>
    void DoTest() {
        enable_if_tester<T> test;
        assert( test() );
    }
};

int main() {
    SomeClass<float>().DoTest<int>();
    return 0;
}

誰かがこれについて説明してくれることを願っています。

4

1 に答える 1

5

コードはすべて問題ありません。VC にバグがあるだけです。テンプレート メンバー クラスの部分的なテンプレート特殊化に問題があることが知られています。

于 2010-07-09T01:32:34.333 に答える