Why does this print "1 1" and not "1 sizeof(int)"?
#include <string>
#include <iostream>
template <class C>
struct streamable
{
~streamable()
{
(*static_cast<std:
stream*>(0)) << (*static_cast<C*>(0));
This will result in undefined behavior if the destructor is ever
executed, and the destructor will never be instantiated unless
it is actuall used (and will be executed). Whatever you're
trying to accomplish here, it won't work. (The title mentionned
SFINAE, but of course, that's completely irrelevant with regards
to whatever may be found in the implementation of a member
function.)
template<typename T>
struct is_streamable
{
static char Test(streamable<T>&);
Requires a reference...
static int Test(...);
static const int value = sizeof(Test((streamable<T>*)(0)));
And here you pass a pointer. So function overloading will never
choose the first function above.
int main()
{
std::cout << is_streamable<A>::value << "\n";
std::cout << is_streamable<int>::value << "\n";
}
Maybe because on your machine sizeof(int) is 1?
I get "4 4" on my Linux box, which is what I'd expect. As
written, there's no code which will ever match the first Test.
If you're trying to distinguish which objects have a << defined
for them, that's something else entirely. Somewhere, you need
a template function declaration whose instantiation depends on
the expression x<<y. Something like:
template <typename T, size_t> struct D{};
template <typename T>
struct is_streamable
{
template <typename U> static char Test(
U*, D<U, sizeof( std::cout << *(static_cast<U*>( 0 )) )>* );
template <typename U> static int Test(U*, ...);
static const int value = sizeof( Test<T>( 0, 0 ) );
};
int main()
{
std::cout << is_streamable<A>::value << "\n";
std::cout << is_streamable<int>::value << "\n";
return 0;
}
Anyway, with the necessary includes added, this compiles and
outputs 4 1 with g++. Not with VC++ (VS 8), however; I suspect that
this is a bug in VC++, but I'm too busy right now to dig into
the standard to be sure. Anyway, SFINAE only comes into play
when attempting to instantiate a function template, so you need
something which gets the expression into a function template
parameters.