SFINAE не работает для условной компиляции шаблона функции-члена - PullRequest
0 голосов
/ 17 декабря 2018

Я пытаюсь использовать std::enable_if, чтобы условно выбрать только один из двух шаблонов функций-членов, используя SFINAE с этим кодом:

#include <iostream>
#include <type_traits>

template<typename T>
struct C {
    template<typename Q = T, typename = typename std::enable_if<std::is_same<Q, int>::value>::type>
    int foo() {
        return 1;
    }

    template<typename Q = T, typename = typename std::enable_if<!std::is_same<Q, int>::value>::type>
    int foo() {
        return 0;
    }

};

int main() {
    std::cout << C<int>().foo() << std::endl;  //error member function foo already defined
}

, но по какой-то причине Visual C ++ продолжает давать мне компиляторошибка, что foo уже определено.Хотя ясно, что, в зависимости от аргумента шаблона класса, только одна функция является правильной.Таким образом, SFINAE должен снять второй вопрос с рассмотрения.

Есть идеи, почему это не работает?

1 Ответ

0 голосов
/ 17 декабря 2018

Попробуйте с

template<typename T>
struct C {
    template<typename Q = T,
             typename std::enable_if<std::is_same<Q, int>::value, bool>::type = true>
    int foo() { // .............................................^^^^^^^^^^^^^^^^^^^^
        return 1;
    }

    template<typename Q = T, 
             typename std::enable_if<!std::is_same<Q, int>::value, bool>::type = true>
    int foo() { // ..............................................^^^^^^^^^^^^^^^^^^^^
        return 0;
    }

};

Дело в том, что в вашем коде SFINAE будет включать / отключать значения по умолчанию для параметра типа шаблона;но значения по умолчанию не участвуют в разрешении перегрузки, поэтому в вашем случае у вас есть две функции

template<typename, typename = void>
int foo() {
    return 1;
}

template<typename, typename>
int foo() {
    return 0;
}

с одинаковой сигнатурой;поэтому компилятор не может выбирать между двумя и выдаст ошибку.

Код, который я предложил, отличается, потому что в случае, если тест std::enable_if ложный, у вас нет типа (элементаслева от =), а не от значения.Что-то вроде

// ................VVVVVV   what is = true ?
template<typename, = true>
int foo() {
    return 1;
}

, что является настоящей «ошибкой замещения», которая отключает метод.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...