Вывод типа шаблона не работает?

Рассмотрим следующий пример.

#include <type_traits>
#include <iostream>
using namespace std;

template <typename T_> 
using Integral = typename std::enable_if<std::is_integral<T_>::value,T_>::type;
template <typename T_> 
using NotIntegral = typename std::enable_if<!std::is_integral<T_>::value, T_>::type;

template <typename T_>
void printIt(const Integral<T_> &value) { cout << "Integral == " << value << endl; }

template <typename T_>
void printIt(const NotIntegral<T_> &value) { cout << "Non Integral == " << value << endl; }

template <typename T_>
void foo(const T_ &value) { printIt<T_>(value); }

int main(int argc, char** argv)
{
    printIt<int>(66);   //Must explicitly provide argument type.
    //printIt(33);        //Compiler error. No overloaded function....????
    foo(29.); 

    return 0;
}

Зачем мне явно указывать тип параметра шаблона? Должен ли компилятор понять, что это аргумент типа int?


person Jacinto Resende    schedule 11.09.2017    source источник


Ответы (1)


Зачем мне явно указывать тип параметра шаблона?

Потому что это невыведенные контексты.

Представьте, что вы специализируетесь на std::enable_if<std::is_integral<T_>::value,T_>, чтобы ::type оценивалось как-то иначе. Компилятор не может знать сопоставление от typename something<T>::type до T.

Вы можете добиться желаемого результата, поместив std::enable_if как часть возвращаемого типа, чтобы несоответствующие перегрузки были исключены SFINAE:

template <typename T>
auto printIt(T x) -> std::enable_if_t<std::is_integral_v<T>, void> { /*...*/ }

template <typename T>
auto printIt(T x) -> std::enable_if_t<!std::is_integral_v<T>, void> { /*...*/ }

живой пример wandbox

person Vittorio Romeo    schedule 11.09.2017