C++ Logo

sg14

Advanced search

Re: [SG14] intrinsic method binding

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Thu, 25 Apr 2019 10:44:17 -0400
On Thu, Apr 25, 2019 at 10:25 AM Farid Mehrabi via SG14 <
sg14_at_[hidden]> wrote:

> Is there any interest enabling deferred call semantics for intrinsic
> method binding with native syntax:
> *std::function<signature> fn=instance.method;*
> IMHO due to spec of member function pointers, std::bind is expensive in
> terms of memory. It also has the downside of too verbose syntax which is
> too complicated for training novice programmers and lacks the ability to
> cover early bound base methods:
> *auto fn=instance.base::method;*
> And lambdas cannot help if code repetition is intended because one would
> need to forward all arguments:
> *auto lam=[&instance](Args...)*
> *{return instance.method(params...);};*
> Thanks in advance.
>

This sounds very similar to the "lifting syntax" proposal briefly mentioned
here:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0573r0.html#Priors
and solidly proposed here:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0834r0.html
https://blog.tartanllama.xyz/passing-overload-sets/

Notice that `instance.method` is already an overload set:

// https://godbolt.org/z/PQPXxa
struct S {
    void method();
    int method(int);
    static void smethod();
    static int smethod(int);
};
S instance;
int main() {
    std::function<int(int)> f = instance.method; // fails, for the same
reason that
    std::function<int(int)> g = S::smethod; // also fails
}

So what you're looking for, at the moment (C++17 and presumably C++2a) is
currently spelled

#define FWD(...) std::forward<decltype(__VA_ARGS__)>(__VA_ARGS__)

#define LIFT(X) [*&*](auto &&... args) \
    noexcept(noexcept(X(FWD(args)...))) \
    -> decltype(X(FWD(args)...)) \
{ \
    return X(FWD(args)...); \
}

which is the same thing Simon Brand gives in his blog post, but with one
additional ampersand (bolded above).

// https://godbolt.org/z/ifa2Hr
int main() {
    std::function<int(int)> f = LIFT(instance.method); // OK
    std::function<int(int)> g = LIFT(S::smethod); // OK
}

HTH,
–Arthur

Received on 2019-04-25 09:46:07