[ 
https://issues.apache.org/jira/browse/MESOS-4994?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Benjamin Bannier updated MESOS-4994:
------------------------------------
    Description: 
libprocess' {{defer}} provides the following overloads

{code}
Deferred<void()> defer(const Process<T>& process, void (T::*method)())
Deferred<void()> defer(const Process<T>* process, void (T::*method)())
Deferred<Future<R>()> defer(const PID<T>& pid, Future<R> (T::*method)())
Deferred<Future<R>()> defer(const Process<T>& process, Future<R> (T::*method)())
Deferred<void()> defer(const PID<T>& pid, void (T::*method)())
Deferred<Future<R>()> defer(const PID<T>& pid, R (T::*method)())
Deferred<Future<R>()> defer(const Process<T>& process, R (T::*method)())
Deferred<Future<R>()> defer(const Process<T>* process, R (T::*method)())
Deferred<Future<R>()> defer(const Process<T>* process, Future<R> (T::*method)())
_Deferred<Future<R>()> defer(const UPID& pid, F&& f)
{code}

Here all overloads but the last require that the first argument is (in a LSP
sense) either a {{Process<T>}} or a {{PID<T>}}, and only member functions of
{{T}} are supported. Consider the following setup,
{code}
struct Base : public Process<Base> {
  double b() { return 0; } // non-const due to MESOS-4995
};

struct Derived : public Base {
  double d() { return 0; } // non-const due to MESOS-4995
};
{code}

We can then {{defer}} for a {{Base}} like
{code}
defer(base, &Base::b);
{code}
which invokes an overload taking {{const Process<T>&}} and {{R 
(T::*method)()}}, but on the other hand use of {{Derived}} is more cumbersome,
{code}
defer(derived.self(), &Derived::d);
{code}
This effectively performs an explicit cast of the {{Derived}} to a 
{{PID<Derived>}} so the overload taking {{const PID<T>&}} and {{R 
(T::*method)()}} can be taken. The overload taking for the {{Base}} case cannot 
be taken here since while {{Derived}} is a {{Process<Base>}}, there exists no 
{{&Base::d}} (like one would have expected).

We should investigate ways to allow the same {{self}}-less {{defer}} syntax for 
both {{Base}} and {{Derived}}-like classes. This might be possible by 
decoupling the types {{T}} for the first and second arguments.



  was:
libprocess' {{defer}} provides the following overloads

{code}
Deferred<void()> defer(const Process<T>& process, void (T::*method)())
Deferred<void()> defer(const Process<T>* process, void (T::*method)())
Deferred<Future<R>()> defer(const PID<T>& pid, Future<R> (T::*method)())
Deferred<Future<R>()> defer(const Process<T>& process, Future<R> (T::*method)())
Deferred<void()> defer(const PID<T>& pid, void (T::*method)())
Deferred<Future<R>()> defer(const PID<T>& pid, R (T::*method)())
Deferred<Future<R>()> defer(const Process<T>& process, R (T::*method)())
Deferred<Future<R>()> defer(const Process<T>* process, R (T::*method)())
Deferred<Future<R>()> defer(const Process<T>* process, Future<R> (T::*method)())
_Deferred<Future<R>()> defer(const UPID& pid, F&& f)
{code}

Here all overloads but the last require that the first argument is (in a LSP
sense) either a {{Process<T>}} or a {{PID<T>}}, and only member functions of
{{T}} are supported. Consider the following setup,
{code}
struct Base : public Process<Base> {
  double b() { return 0; } // non-const due to MESOS-XXXX
};

struct Derived : public Base {
  double d() { return 0; } // non-const due to MESOS-XXXX
};
{code}

We can then {{defer}} for a {{Base}} like
{code}
defer(base, &Base::b);
{code}
which invokes an overload taking {{const Process<T>&}} and {{R 
(T::*method)()}}, but on the other hand use of {{Derived}} is more cumbersome,
{code}
defer(derived.self(), &Derived::d);
{code}
This effectively performs an explicit cast of the {{Derived}} to a 
{{PID<Derived>}} so the overload taking {{const PID<T>&}} and {{R 
(T::*method)()}} can be taken. The overload taking for the {{Base}} case cannot 
be taken here since while {{Derived}} is a {{Process<Base>}}, there exists no 
{{&Base::d}} (like one would have expected).

We should investigate ways to allow the same {{self}}-less {{defer}} syntax for 
both {{Base}} and {{Derived}}-like classes. This might be possible by 
decoupling the types {{T}} for the first and second arguments.




> Overloads for defering member function invocations match too tightly
> --------------------------------------------------------------------
>
>                 Key: MESOS-4994
>                 URL: https://issues.apache.org/jira/browse/MESOS-4994
>             Project: Mesos
>          Issue Type: Bug
>          Components: libprocess
>            Reporter: Benjamin Bannier
>            Priority: Minor
>              Labels: beginner, mesosphere, newbie, newbie++
>
> libprocess' {{defer}} provides the following overloads
> {code}
> Deferred<void()> defer(const Process<T>& process, void (T::*method)())
> Deferred<void()> defer(const Process<T>* process, void (T::*method)())
> Deferred<Future<R>()> defer(const PID<T>& pid, Future<R> (T::*method)())
> Deferred<Future<R>()> defer(const Process<T>& process, Future<R> 
> (T::*method)())
> Deferred<void()> defer(const PID<T>& pid, void (T::*method)())
> Deferred<Future<R>()> defer(const PID<T>& pid, R (T::*method)())
> Deferred<Future<R>()> defer(const Process<T>& process, R (T::*method)())
> Deferred<Future<R>()> defer(const Process<T>* process, R (T::*method)())
> Deferred<Future<R>()> defer(const Process<T>* process, Future<R> 
> (T::*method)())
> _Deferred<Future<R>()> defer(const UPID& pid, F&& f)
> {code}
> Here all overloads but the last require that the first argument is (in a LSP
> sense) either a {{Process<T>}} or a {{PID<T>}}, and only member functions of
> {{T}} are supported. Consider the following setup,
> {code}
> struct Base : public Process<Base> {
>   double b() { return 0; } // non-const due to MESOS-4995
> };
> struct Derived : public Base {
>   double d() { return 0; } // non-const due to MESOS-4995
> };
> {code}
> We can then {{defer}} for a {{Base}} like
> {code}
> defer(base, &Base::b);
> {code}
> which invokes an overload taking {{const Process<T>&}} and {{R 
> (T::*method)()}}, but on the other hand use of {{Derived}} is more cumbersome,
> {code}
> defer(derived.self(), &Derived::d);
> {code}
> This effectively performs an explicit cast of the {{Derived}} to a 
> {{PID<Derived>}} so the overload taking {{const PID<T>&}} and {{R 
> (T::*method)()}} can be taken. The overload taking for the {{Base}} case 
> cannot be taken here since while {{Derived}} is a {{Process<Base>}}, there 
> exists no {{&Base::d}} (like one would have expected).
> We should investigate ways to allow the same {{self}}-less {{defer}} syntax 
> for both {{Base}} and {{Derived}}-like classes. This might be possible by 
> decoupling the types {{T}} for the first and second arguments.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to