Кто-нибудь знает метод специализации шаблона в зависимости от того, определен ли метод, не являющийся членом? Я знаю, что существует множество способов специализации, если функция-член существует, но я никогда не видел примера, не являющегося членом. Конкретная проблема заключается в том, чтобы специализировать оператора ‹< для shared_ptr, чтобы он применил оператор ‹<, если оператор ‹* определен для T, и распечатал просто местоположение указателя в противном случае. Было бы здорово, если бы все классы определили оператор ‹< как член, но, к сожалению, многие используют бесплатные функции. Я представляю себе что-то вроде следующего:
template <typename T>
typename enable_if< ??? ,std::ostream &>::type operator<<( std::ostream & os, const shared_ptr<T> & ptr )
{
if(ptr)
return os << *ptr;
else
return os << "<NULL>";
}
template <typename T>
typename disable_if< ??? ,std::ostream &>::type operator<<( std::ostream & os, const shared_ptr<T> & ptr )
{
if(ptr)
return os << static_cast<intptr_t>( ptr.get() );
else
return os << "<NULL>";
}
Изменить: для потомков это было рабочее решение. Обратите внимание, что boost :: shared_ptr уже имеет оператор по умолчанию ‹<, который выводит адрес, поэтому disable_if не требуется. Поскольку оператор ‹< возвращает ссылку, это работает. Я подозреваю, что в общем случае это должно быть адаптировано для отражения типа возвращаемого значения рассматриваемой функции.
template <typename T>
typename boost::enable_if_c< boost::is_reference<decltype(*static_cast<std::ostream *>(0) << *static_cast<T *>(0) )>::value, std::ostream &>::type operator<<( std::ostream & os, const boost::shared_ptr<T> & ptr )
{
if(ptr)
return os << *ptr;
else
return os << "<NULL>";
}