SFINAE To detect the existence of a non-member function

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>"; } 
+3
c ++ sfinae
source share
1 answer

If you are using C ++ 0x, you can just use decltype.

 template<typename Char, typename CharTraits, typename T> decltype( *(std::basic_ostream<Char, CharTraits>*)(nullptr) << *(T*)(nullptr) ) 

This will certainly cause a replacement failure if T cannot be deduced. Perhaps you could do something similar in C ++ 03, but I'm not sure how to do it.

Edit: just realized that the decltype expression does not actually produce a true or false value and will not compile. But you get the picture. Try it.

+2
source share

All Articles