cartec69@gmail.com wrote:
On Thursday, June 21, 2012 7:59:23 AM UTC-5, Gerhard Fiedler wrote:
I'm still working on getting my original approach to work (please see
my other post in this thread if you're interested). I'm not yet
understanding well enough how I can limit the matching.
See http://stackoverflow.com/questions/257288/is-it-possible-to-write-a-c-template-to-check-for-a-functions-existence
for a very good discussion of how to detect a member function.
Applying the principles discussed there to your program:
#include<iostream>
#include<type_traits>
template<typename T>
class is_printable
{
typedef char yes[1];
typedef char no[2];
template<typename C> static yes& test( decltype(&C::print) );
template<typename C> static no& test(...);
public:
static const bool value = (sizeof(test<T>(0)) == sizeof(yes));
};
template< class Printable>
typename std::enable_if<is_printable<Printable>::value,std::ostream&>::type
operator<<( std::ostream&stream, Printable const&printable )
{
printable.print( stream );
return stream;
}
class MyClass
{
public:
MyClass( char const *val ) : str( val ) {}
void print( std::ostream&stream ) const { stream<< str; }
private:
char const *str;
};
int main(int argc, char* argv[])
{
std::cout<< MyClass( "bar" )<< std::endl;
}
If you have types in your codebase that you want to exclude - say they
have a print member that serves some other purpose - you can do so
with a specialization:
template<>
class is_printable<Foo>
{ public: static const bool value = false; };
Thanks!
At first I thought this works as I want it, but then I ran into this
snag. Google Test defines a function like this:
template<typename T>
void GTestStreamToHelper(std::ostream* os, const T& val) {
*os<< val;
}
I invoke it like this (for testing resolution):
int main(int argc, char* argv[])
{
MyClass foo( "bar" );
std::cout<< "test "<< foo<< std::endl;
std::string const gtest( "gtest" );
GTestStreamToHelper(&std::cout, gtest );
std::cout<< std::endl;
}
For some reason, my operator<<() gets chosen for the '<<' inside
GTestStreamToHelper, then it complains that std::string doesn't have a
print() method. Shouldn't it use a different operator<<() definition?
It will use the template that matches better. Unless the compiler has a
bug in it, that is. Please post the shortest code to replicate the
situation. Do so every time you need help with code not compiling or
not running the way you expect (again, see FAQ 5.8).