Boost logo

Boost Users :

Subject: Re: [Boost-users] puzzle with enable_if
From: Gevorg Voskanyan (v_gevorg_at_[hidden])
Date: 2010-04-21 13:56:52


John Dlugosz wrote:
> OK, so "refactoring" in general won't work.

It will, at least I've yet to encounter a case which can't be refactored properly. Some special care must be taken in some cases though, like in the one in your original post.

> The SFINAE must be directly caused by
> the template specialization mentioned in the function declaration.

The attempted template specialization shall be an invalid type itself (before the compiler can even consider to "instantiate" it) for it to cause SFINAE. Any errors that are delayed until the instantiation (such as an invalid base class type, as in your OP) will cause hard errors and not SFINAE as they are not in the "immediate context".

> Your case f (struct A contains T::value_type) is a failure of A to specialize.

It is a failure of A to *instantiate* with T=double. A< double > specialization is an otherwise valid type, as opposed to e.g. A< double::value_type > which is not.

> My example where the function returned something derived from A, say struct A2 :
> A { ..., is not a failure of A2 but of a type needed by it.

This is no different from the case above. It is still a failure of A2 to instantiate. The fact that the error is in a type needed by A2 doesn't matter here as the base class' type is needed at A2's instantiation time and no sooner, and A2's specialization was a valid type by itself, so the error caused by base class type being invalid happens at A2's instantiation time when it is too late for SFINAE and the result is a hard error.

> T::value_type
> is still a dependant type, I would have thought, but I see that the error is the
> use of T:: that is a part of A's syntax. The difference is a nested call
> to have a template instantiated.

Trying to summarize, if you want erroneous template parameter substitutions to result in SFINAE and not hard error, you should define the metafunctions you use in a function declaration in a way, such that if the specialization is a valid type by itself, its instantiation will always succeed. The trick to make the dependent types and expressions used in the template definition as default arguments for newly introduced template parameters often comes handy for doing that, as I've shown earlier in this thread.

> Is that the right track?

It seems pretty close. I hope you enjoyed this journey ;)

Best Regards,
Gevorg


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net