Я изучаю SFINAE, и это моя первая попытка напечатать "ДА" только для тех типов, которые вы можете выводить с помощью std::ostream
(забудьте о std::operator<<(std::ostream &, T)
сейчас...):
template <typename T>
void f(const T &) { std::cout << "NO" << std::endl; }
template <typename T, int SFINAE = sizeof(static_cast<std::ostream &(std::ostream::*)(T)>(
&std::ostream::operator<<))>
void f(const T &) { std::cout << "YES" << std::endl; }
Хотя они, похоже, работают с f(std::vector<int>())
(уступая "НЕТ" ), компилятор жалуется, что f(0)
неоднозначен: http://ideone.com/VljXFh
prog.cpp:16:5: error: call of overloaded 'f(int)' is ambiguous
f(0);
^
prog.cpp:6:6: note: candidate: void f(const T&) [with T = int]
void f(const T &) { std::cout << "NO" << std::endl; }
^
prog.cpp:10:6: note: candidate: void f(const T&) [with T = int; int SFINAE = 8]
void f(const T &) { std::cout << "YES" << std::endl; }
^
Как я могу исправить свой код? Является ли версия "ДА" не более конкретной, чем версия "НЕТ", которая является полностью общей?
Разъяснение
Все f(0)
, f(0.)
и f(true)
терпят неудачу с той же "двусмысленной" ошибкой. Я ищу решение, применимое ко всем типам, принятым std::ostream::operator<<
. В идеале он не должен полагаться на определение вспомогательного типа, который "заглушает" пространство имен.