
On Sun, Sep 12, 2010 at 8:11 AM, Mathias Gaunard <mathias.gaunard@ens-lyon.org> wrote:
On 12/09/2010 09:18, Thomas Heller wrote:
My take would be to use boost::result_of<Expr(T1, T2, ...)>::type before calling the phoenix expression and use SFINAE here.
I don't understand what you mean, and how that would help at all.
What needs to be in an SFINAE context, here, is something of the kind decltype(make_mutable<T0>() << make_mutable<T1>()), with T0 and T1 template parameters.
I'm not sure if this could work. The C++0x draft is pretty specific about the context in which substitution failure is allowed, namely, it's only allowed in the immediate context of the function and not as a side effect of instantiating a template (such as a Proto class). Here's the relevant language from 14.8.2. "Only invalid types and expressions in the immediate context of the function type and its template parameter types can result in a deduction failure. [ Note: The evaluation of the substituted types and expressions can result in side effects such as the instantiation of class template specializations and/or function template specializations, the generation of implicitly-defined functions, etc. Such side effects are not in the “immediate context” and can result in the program being ill-formed. — end note ]" However, I just checked, and I was pleased to find that gcc 4.5 is now accepting some SFINAE for expressions. typedef char (&pass)[1]; typedef char (&fail)[2]; template<class T> fail has_addition(...); template<class T> pass has_addition(decltype(T() + T())*); struct S { }; int main() { static_assert( sizeof(has_addition<int>(0)) == sizeof(pass) , "unexpected substitution failure" ); static_assert( sizeof(has_addition<S>(0)) == sizeof(fail) , "unexpected substitution success" ); } I think this method could be developed, eventually, to enable rich, expression-based introspection of types. Daniel Walker