Странное поведение enable_if с использованием вложенных классов (ошибка компилятора MSVC или функция?) - PullRequest
5 голосов
/ 09 июля 2010

Через некоторое время после отладки кода я обнаружил причину моих проблем с некоторыми неожиданными результатами специализации шаблона, используя enable_if:

Следующий код не соответствует утверждению в DoTest () в Visual Studio 2010 (и2008), а в g ++ - нет 3.4.5.Однако, когда я удаляю шаблон из SomeClass или перемещаю my_condition из области действия SomeClass , он также работает в MSVC.

Isчто-то не так с этим кодом, который объясняет это поведение (по крайней мере, частично), или это ошибка в компиляторе 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;
}

Надеюсь, у кого-то есть объяснение этому.

1 Ответ

5 голосов
/ 09 июля 2010

Все в порядке с вашим кодом, просто VC глючит. Известно, что есть проблемы с частичной специализацией шаблонов классов-членов шаблона.

...