5

To create std::function, here is what I do:-

std::function<void(int,int,int)> f =
    std::bind(&B::fb,this,
        std::placeholders::_1,
        std::placeholders::_2,
        std::placeholders::_3
    );  

void B::fb(int x,int k,int j){} //example

It is obvious that B::fb receive three parameters.
To increase readability & maintainability, I wish I could call this instead :-

std::function<void(int,int,int)> f=std::bind(&B::fb,this);  //omit _1 _2 _3

Question
Are there any features in C++ that enable omitting the placeholders?
It should call _1,_2, ..., in orders automatically.

I have googled "omit placeholders c++" but not find any clue.

Jarod42
  • 203,559
  • 14
  • 181
  • 302
javaLover
  • 6,347
  • 2
  • 22
  • 67
  • 4
    You can't omit the placeholders. Remember that `B::fb` might be overloaded. – KayEss Jul 31 '16 at 05:14
  • Then, make it throw the "ambiguous" compile error to me. – javaLover Jul 31 '16 at 05:16
  • Well, it does throw an error right now if you omit paceholders. Not an "ambiguius" one, but close enough. – Revolver_Ocelot Jul 31 '16 at 05:48
  • Thank. I don't want compiler error when the placeholders are omitted. The compiler error as mentioned is expected to happen only if `B::fb` is overloaded. – javaLover Jul 31 '16 at 05:54
  • 1
    You know that `B::fb` isn't overloaded, but the language specification doesn't know that. There are some retrospection papers working their way towards standardisation. You probably need to wait for that before you can solve this. – KayEss Jul 31 '16 at 06:01
  • 1
    @KayEss B::fb can be overloaded with the same number of arguments just as well, and the compiler will produce an error in such case. – n. m. could be an AI Jul 31 '16 at 06:14
  • Why don't you use a lambda with `auto...` as a parameter to be forwarded to the right function? – skypjack Jul 31 '16 at 07:32
  • Would [curry](https://stackoverflow.com/q/26655685/1774667) solve your problem? – Yakk - Adam Nevraumont Jul 31 '16 at 18:10
  • 1
    use [std::bind_front](https://en.cppreference.com/w/cpp/utility/functional/bind_front) since >= c++20 – ridilculous Jan 23 '23 at 18:12

1 Answers1

9

You may create functions helper (those ones are C++14):

template <class C, typename Ret, typename ... Ts>
std::function<Ret(Ts...)> bind_this(C* c, Ret (C::*m)(Ts...))
{
    return [=](auto&&... args) { return (c->*m)(std::forward<decltype(args)>(args)...); };
}

template <class C, typename Ret, typename ... Ts>
std::function<Ret(Ts...)> bind_this(const C* c, Ret (C::*m)(Ts...) const)
{
    return [=](auto&&... args) { return (c->*m)(std::forward<decltype(args)>(args)...); };
}

and then just write

std::function<void(int, int, int)> f = bind_this(this, &B::fb);
Jarod42
  • 203,559
  • 14
  • 181
  • 302