Victor Bazarov wrote:
This:
---------------------------------------------->8 cut here
#include<iostream>
#include<type_traits>
#include<string>
template<typename T>
class is_printable
{
typedef char yes[1];
typedef char no[2];
template<typename C> static yes& test( decltype(&C:
rint) );
template<typename C> static no& test(...);
public:
static const bool value = (sizeof(test<T>(0)) == sizeof(yes));
};
template<> class is_printable<std::string> {
public: static const bool value = false;
};
template< class Printable>
typename
std::enable_if<is_printable<Printable>::value,std:
stream&>::type
operator<<( std:
stream&stream, Printable const&printable )
{
printable.print( stream );
return stream;
}
class MyClass
{
public:
MyClass( char const *val ) : str( val ) {}
void print( std:
stream&stream ) const { stream<< str; }
private:
char const *str;
};
template<typename T>
void GTestStreamToHelper(std:
stream* os, const T& val) {
*os<< val;
}
int main()
{
MyClass foo( "bar" );
std::cout<< "test "<< foo<< std::endl;
std::string const gtest( "gtest" );
GTestStreamToHelper(&std::cout, gtest );
std::cout<< std::endl;
}
---------------------------------------------->8 cut here
compiled for me fine with Visual C++ 2010. And the output was
test bar
gtest
Does that solve your problem?
I see... thanks for following up on this.
I can't (yet) tell whether this solves my problem -- because don't (yet)
understand how this works, and what I may have to do to make it work
generally.
When GTestStreamToHelper is used with T=std::string, it looks for an
operator<<( std:
stream&stream, std::string const& ), right? Why
doesn't it pick the right one, without explicit help? Shouldn't the
generic definition of is_printable tell it that std::string doesn't have
a print() member function?
The whole idea behind is_printable is that it is /automatically/ false
for classes that don't provide a print() member function. I don't
understand why it is necessary to explicitly tell the compiler that
std::string doesn't have one if it already knows this... Can somebody
please explain why this is necessary?
If I have to provide such an explicit "false" declaration for every
class that may be used as T with GTestStreamToHelper (and with any other
template function that may use an ostream operator<<), for me this
doesn't work.