I want to have several overloaded, global to_string()
functions that take some type T
and convert it to its string representation. For the general
The initializer of value
on line 48 is not in a context where SFINAE works. Try moving the expression to the function declaration.
#include <iostream>
struct sfinae_base {
typedef char yes[1];
typedef char no[2];
};
template<typename T>
struct has_insertion_operator : sfinae_base {
// this may quietly fail:
template<typename U> static yes& test(
size_t (*n)[ sizeof( std::cout << * static_cast<U*>(0) ) ] );
// "..." provides fallback in case above fails
template<typename U> static no& test(...);
static bool const value = sizeof( test<T>( NULL ) ) == sizeof( yes );
};
However, I have to question the amount of sophistication that is going into this. I see non-orthogonal mechanisms that will grind against each other (to_string
vs. operator<<
) and I hear poor assumptions getting tossed around (for example that operator<<
is global vs a member, although the code as implemented looks OK in that regard).
I should have simply been more faithful to this answer. A working implementation is:
namespace has_insertion_operator_impl {
typedef char no;
typedef char yes[2];
struct any_t {
template<typename T> any_t( T const& );
};
no operator<<( std::ostream const&, any_t const& );
yes& test( std::ostream& );
no test( no );
template<typename T>
struct has_insertion_operator {
static std::ostream &s;
static T const &t;
static bool const value = sizeof( test(s << t) ) == sizeof( yes );
};
}
template<typename T>
struct has_insertion_operator :
has_insertion_operator_impl::has_insertion_operator<T> {
};
I believe that it does not actually rely on SFINAE.