Меня немного раздражают ошибки компиляции, которые возникают, когда я пытаюсь написать std::cout << x
, а оператор сдвига влево не определен для x
. Не могу преобразовать x в это, не могу преобразовать x в это... Несколько экранов с бесполезными сообщениями об ошибках.
Я хочу специализировать operator<<(std::ostream&, const T&)
для всех типов, для которых еще не определен такой оператор. Внутри я мог бы поместить, скажем, статическое утверждение и сделать сообщение об ошибке компиляции намного яснее, чем сейчас.
Моя первая попытка заключалась в следующем.
template<typename T, typename = void>
struct Has : public std::false_type {};
template<typename T>
struct Has<T, decltype(void(
std::declval<std::ostream&>() << std::declval<T>()
))> : public std::true_type {};
template<typename T>
auto operator<<(std::ostream& out, const T&)
-> typename std::enable_if<
!Has<T>::value,
std::ostream&>::type
{
return out << "my operator";
}
Не удается скомпилировать, поскольку превышена максимальная глубина шаблона. Действительно, мой operator<<
вызывает Has
специализацию, которая по порядку вызывает operator<<
, где моя перегрузка проверяется еще раз, и так далее, и так далее, и так далее.
Самый простой вариант тоже не работает: неоднозначная перегрузка для std::ostream& << const char*
. Что ж, ожидаемо.
template<typename T>
std::ostream& operator<<(std::ostream& out, const T&)
{
return out << "my operator";
}
Как я могу выполнить задание? Или вообще, как определить функцию для всех типов аргументов, кроме тех, которые уже могут быть переданы в функцию?
<<
менее привлекательным, а не тестируете<<
, может сработать; в качестве альтернативы вы можете написать свой собственный оператор потоковой передачи, который использует<<
, если он существует, а в противном случае генерирует статическое утверждение. - person Yakk - Adam Nevraumont   schedule 23.10.2017template <typename T> std::enable_if_t<Has<T>::value> print(std::ostream& out, const T&t) {return out << t;}
и аналогичные дляstd::enable_if_t<!Has<T>::value>
. - person Jarod42   schedule 23.10.2017<<
, но будьте осторожны, если я случайно использую его с несовместимым типом. Я попытался аргументировать это в комментариях к ответу. - person Ivan Smirnov   schedule 23.10.2017