enable_if в функции шаблона члена шаблона класса

Похоже, это ошибка в MSVC10?

#include <type_traits>

template<int j>
struct A{
    template<int i>
    typename std::enable_if<i==j>::type
        t(){}
};

int main(){
    A<1>().t<1>();  //error C2770
}

ошибка C2770: неверный явный аргумент(ы) template_or_generic "enable_if::type A::t(void)".

Компилируется следующее:

#include <type_traits>

template<class j>
struct A{
    template<class i>
    typename std::enable_if<std::is_same<i,j>::value>::type
        t(){}
};

template<unsigned int j>
struct B{
    template<unsigned int i>
    typename std::enable_if<i==j>::type
        t(){}
};

int main(){
    A<int>().t<int>();
    B<1>().t<1>();
}

person Johannes Gerer    schedule 16.12.2011    source источник
comment
Работает в g++ и clang++. У вас есть #include <type_traits> и using std::enable_if?   -  person kennytm    schedule 16.12.2011
comment
В чем ошибка? Не пишите не работает. Что вы имеете в виду под не работает? Не компилируется или что?   -  person Nawaz    schedule 16.12.2011
comment
Как ни странно, MSVC10 кажется счастливым, если вы измените тип обоих параметров шаблона на unsigned int или даже long. Это может быть приемлемым решением для вас.   -  person Praetorian    schedule 16.12.2011
comment
Нет заголовка с именем <typetraits>. Должно быть <type_traits>   -  person Nawaz    schedule 16.12.2011
comment
Это работает для char, bool, size_t или long и работает для int, не равного 0 или 1! (ну я проверил на 2). См. stackoverflow.com/questions/2763836/ для связанной проблемы.   -  person TemplateRex    schedule 21.07.2012


Ответы (1)


Похоже, это какое-то странное поведение со стороны MSVC2010, когда он не может определить, является ли использование вами ‹1> в качестве параметра шаблона экземпляром шаблона на основе int.

Когда я компилирую ваш код выше, я получаю следующую подробную ошибку:

    error C2770: invalid explicit template argument(s) for 
    'std::enable_if<i==1>::type A<j>::t(void)'
    with
    [
        j=1
    ]
    d:\programming\stackoverflow\stackoverflow\stackoverflow.cpp(11) : 
    see declaration of 'A<j>::t'
    with
    [
        j=1
    ]

Если вы замените свои значения 1 на 0, вы обнаружите, что это все еще не работает, но если вы используете любое другое допустимое целое число, шаблон, похоже, вполне успешно компилируется.

Я не совсем уверен, почему это происходит, но вы можете заставить этот код работать, используя const int для представления параметров шаблона:

    template<int j>
    struct A{
        template<int i>
        typename std::enable_if<i == j>::type
            t(){}
    };

    int main(){

        const int j = 1;
        const int i = 1;

        A<j>().t<i>();   //now compiles fine
    }

Мое подозрение, основанное на этом, заключается в том, что компилятор считает использование 0 и 1 неоднозначным, когда дело доходит до создания экземпляра шаблона. Надеюсь, обходной путь здесь поможет кому-то, кто наткнется на это через Google...

person Fritz    schedule 20.11.2012