[ https://issues.apache.org/jira/browse/MESOS-4611?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15223603#comment-15223603 ]
Michael Park commented on MESOS-4611: ------------------------------------- I'm happy to shepherd this if someone would like to write a patch. The issue is not that lambdas are not implicitly convertible to a {{std::function}}. They absolutely are. However, for a function parameter with a template parameter which is deduced, the argument must be of exact type. Recall that the type of a lambda is an anonymous type generated by the compiler, not {{std::function}}. With that in mind, consider this small example: {code} template <typename T> struct S{ S(int); }; template <typename U> void F(S<U>); {code} Although {{int}} is implicitly convertible to {{S<T>}} for any {{T}}, Given {{F(42)}}, the compiler has no idea what to deduce {{U}} to be. We can however, do: {code} S<double> x = 42; // The `double` is irrelevant. F(x); // `T` can be deduced to be `double`. {code} If you were to replace {{S}} with {{std::function}}, {{42}} with the lambda, {{F}} with {{dispatch}}, you'll see that everything is consistent. Now, for the fix we need to use a similar technique as the one we use in {{future.hpp}}. That is, rather than using {{std::function}}, we simply use a template parameter {{F}} and use {{result_of}} to constrain it correctly. For example, {code} template <typename R> Future<R> dispatch(const UPID& pid, const std::function<R()>& f); {code} should be something like: {code} template <typename F> Future<typename result_of<F()>::type> dispatch(const UPID& pid, F&& f); {code} It's not that straight-forward since there are 3 overloads, but as I said, I can help out with this. > Passing a lambda to dispatch() always matches the template returning void > ------------------------------------------------------------------------- > > Key: MESOS-4611 > URL: https://issues.apache.org/jira/browse/MESOS-4611 > Project: Mesos > Issue Type: Bug > Components: libprocess > Reporter: Kevin Klues > Labels: dispatch, libprocess, mesosphere > > The following idiom does not currently compile: > {code} > Future<Nothing> initialized = dispatch(pid, [] () -> Nothing { > return Nothing(); > }); > {code} > This seems non-intuitive because the following template exists for dispatch: > {code} > template <typename R> > Future<R> dispatch(const UPID& pid, const std::function<R()>& f) > { > std::shared_ptr<Promise<R>> promise(new Promise<R>()); > > std::shared_ptr<std::function<void(ProcessBase*)>> f_( > new std::function<void(ProcessBase*)>( > [=](ProcessBase*) { > promise->set(f()); > })); > internal::dispatch(pid, f_); > > return promise->future(); > } > {code} > However, lambdas cannot be implicitly cast to a corresponding > std::function<R()> type. > To make this work, you have to explicitly type the lambda before passing it > to dispatch. > {code} > std::function<Nothing()> f = []() { return Nothing(); }; > Future<Nothing> initialized = dispatch(pid, f); > {code} > We should add template support to allow lambdas to be passed to dispatch() > without explicit typing. -- This message was sent by Atlassian JIRA (v6.3.4#6332)