Hi all,
I've just read n4495 and it seems pretty nice. My only suggestion is to make the synthesized function type stateless and polymorphic. Parameters should be passed explicitly to operator. that will forward them explicitly to the function object.
This allows for explicit control of the capture type (by value/reference) and for transformations to be applied to parameters.
Use case:
template<class T>
T&& unwrap(T&&) { return t; }
template<class T>
T unwrap(future<T>&&) { return t.get(); }
template<class T>
using unwrap_t = decltype(unwrap(std::declval<T>()));
template<class T>
future<T> wrap(T&&) { return make_ready_future<T>(); }
template<class T>
future<T>&& wrap(future<T>&&) { return t; }
template<class... T>
bool is_future = !std::is_same<T, unwrap_t<T> > || ... ; // fold expression
template<class T>
AsyncProxy
{
T x;
// sfinae if underlying expression is invalid
template<class... Args, class Ret = std::result_of_t<F(unwrap_t<Args>...)>
auto operator.(F f, Args&&...args) -> std::future<Ret>
return is_future<Args...> ?
when_all(wrap(std::forward<Args>(args))...).then(f) :
std::async(f, std::forward<Args>(args)...);
}
};
struct Parm { ... };
struct Result {...};
struct SomeObject
{
Parm doSomething(const Result&);
};
std::future<Param> arg = ....;
AsyncProxy<SomeObject> x = ...;
auto ret = x.doSometing(x);
I'm sure I got some of the forwarding wrong, but you get the general idea.
HTH,
-- gpd