This is a follow-up of another question. It refers to the same problem (I hope) but uses an entirely different example to illustrate it. The reason is that in the previous examp
This does not answer the question whether the code above is valid, but is a quite pretty workaround that I have found by experimenting shortly after asking the question, and I think is useful to share.
All that is needed are the following definitions:
template class F>
struct temp { };
template class F>
F subs_fun(temp );
template class F, typename... A>
using subs = decltype(subs_fun (temp ()));
then, wherever F
would be problematic, replace it with subs
. That's it. I cannot explain why, but it has worked in all cases so far.
For instance, in the SFINAE example of the question, just replace line
template static pass > _(int);
by
template static pass > _(int);
This is a change at one point only, all remaining code stays the same. You don't need to redefine or wrap every template metafunction that with be used as F
. Here's a live example.
If F
is indeed valid and compilers support it eventually, it is again easy to switch back because changes are minimal.
I find this important because it allows specifying a SFINAE test in just two lines
template using type_of = typename T::type;
template using has_type = sfinae ;
and is completely generic. Typically, each such test needs at least 10 lines of code and implementations of
are full of such code. In some cases such code blocks are defined as macros. With this solution, templates can do the job and macros are not needed.