
Mathias Gaunard wrote:
I would quite like it if polymorphic function objects created by Phoenix could restrict overload resolution to types for which their function body is valid, using SFINAE for expressions.
Basically, this would allow something like this:
struct foo {};
void dummy_function(...) { std::cout << "[not streamable]"; }
make_overload( std::cout << arg1, dummy_function ) (foo());
(with make_overload what you'd expect)
The dummy function would be called if the first one doesn't match, instead of resulting in a hard error. (surely it would also be nice to add a module to create "..." functions in Phoenix, but that should be easy)
Now I looked a bit at how Phoenix v3 and Proto work, and it seems the main problem to do that is in the default transform.
Albeit it uses decltype for its return type, this is not done in a template deduction context, which prevents it from doing its SFINAE magic. I tried to do that, but then a transform is assumed everywhere to be monomorphic, so SFINAE doesn't "propagate" out of default_TAG.
Before I go ahead and try to convert all result_type to result with templates, which could affect compile-time, I'd like to have some feedback on the whole idea, and whether this is the right way to do it.
Phoenix3 uses result_of protocol, and result_type wherever the return type is monomorphic. My take would be to use boost::result_of<Expr(T1, T2, ...)>::type before calling the phoenix expression and use SFINAE here.