On 9/7/07 3:42 PM, in article
46e1d3f5$0$28521$5a62a...@per-qv1-newsreader-01.iinet.net.au, "Gianni
Mariani" <gi3nos...@mariani.ws> wrote:
Below is an attempt to factorize the "SFINAE" idiom. I have tried it on
three compilers and they all complain. As far as I can tell, it's valid
code. The questions are, are the compilers right to reject the code or
is the code right and why ? and has anyone successfully mastered the act
of factorizing SFINAE?
----------------------------------------------------------------------
template <template <typename> class w_Test, typename w_Type>
class sfinae_test
{
typedef char (&false_value)[1];
typedef char (&true_value)[2];
struct base {};
struct derived : base {};
static derived & make_derived();
static w_Type& make_test();
template <bool i>
struct H
{
};
template <typename Z>
static false_value func( Z &, base & );
template <typename Z>
static true_value func(Z&, derived&, typename w_Test<Z>::type* =0 );
public:
static const bool value =
sizeof(func(make_test(), make_derived())) == sizeof(true_value);
};
// some tests
// is_defined_test will fail if T is not defined
template <typename T> class is_defined_test
{
typedef char (&type)[ sizeof( T ) ];
};
// has_member_orange will fail if T had no orange
template <typename T> class has_member_orange
{
static T& make_T();
public:
typedef char (&type)[ sizeof( make_T().orange ) ];
};
There is no example of SFINAE ("substitution failure is not an error") in
the this program; both has_member_orange<A> and is_defined_test<B> match
func()'s second parameter:
typename w_Test<Z>::type
because both template classes do declare an interior typedef named "type".
Now, the compiler does run into trouble instantiating has_member_orange<A>
and is_defined_test<B> (because the "type" typedef is ill-formed)- but this
error occurs only after the type deduction needed to select func() has
already been performed. So the ill-formed template specialization error
comes too late for SFINAE to help - so the result is a compile-time error.
Greg
sorry for bringing this out again but it was just too interesting.