Does anyone know a method for specializing a template depending on whether a non-member method is defined? I know that there are many ways to specialize if a member function exists, but I have never seen an example that is not a member. A specific task specializes in the operator <for shared_ptr to use the operator <<if the operator <is defined for T and otherwise prints a simple pointer location. It would be great if all classes defined the <<operator as a member, but, unfortunately, many use free functions. I imagine something like the following:
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>"; }
Edit: for posterity, there was a working solution here. Note that boost :: shared_ptr already has a default operator <<that prints the address, so disable_if is not required. Since the <operator returns a link, this works. In the general case, I suspect that this would have to be adapted to reflect the type of function returned.
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>"; }
c ++ sfinae
tgoodhart
source share