0

I saw this type here. I believe he's trying to create a variable pf for a member pointer type-erased (that's why there's void* there). I then noticed this type signature in similar such classes.

But according to isocpp a non-static member pointer type is defined like this: int (Fred::*)(char,float) (for some class Fred) and a function pointer type is defined like this: int (*)(char,float)

Therefore one would create a member pointer variable mp like this: int (S::*mp)(int) = nullptr;

Maybe this void* represents this* and its another way to define a member pointer variable by defining a function pointer variable? Is this possible?

What is R(*pf)(void*, Args...)?

KeyC0de
  • 4,728
  • 8
  • 44
  • 68

2 Answers2

3

It's the declaration of a function pointer. Nothing more than that.

Compatible functions take void* and Args..., and return R.

In the given example, the compatible function that's assigned to the pointer, is a lambda. The void* is the type-erased address of some callable f, and the Args... members are, well, the arguments that'll be passed to that callable. The callable's type is restored by capturing of type aliases inside the lambda (nice!).

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • If `pf` is a function pointer to a Callable as defined [here](https://en.cppreference.com/w/cpp/named_req/Callable) then this is a generic way to define any kind of function pointer, member pointer or data member pointer in C++. I found this [page](https://en.cppreference.com/w/cpp/named_req/Callable) for the `INVOKE(f, t1, t2, ..., tN)` operation, which expands the `void*` and the `Args...` arguments accordingly depending on which type of callable it is (function pointer, member pointer, data member pointer). Am I correct? – KeyC0de Sep 21 '19 at 22:25
  • @Nikos: Yes, as the answer states, it's a [simple] reimplementation of `std::function` which is a class-based wrapper around callables. – Lightness Races in Orbit Sep 21 '19 at 22:26
  • Ok, this is very interesting stuff. I wasn't sure about this. Thanks for answering. – KeyC0de Sep 21 '19 at 22:27
  • 1
    @Nikos: Note that, as is also [briefly] explained on the answer, it's more of a wrapper around a pointer-to-a-callable in that it's just a "view". It doesn't copy the callable. It stores a pointer to it. So, unlike with `std::function`, you have to make sure the callable survives long enough for you to make your call. That may or may not be a problem when you use this approach, as some callables don't live very long (although since this approach is incompatible with functors I'm not aware of any obvious examples up-front) – Lightness Races in Orbit Sep 21 '19 at 22:28
  • Yes I understand! I was looking into `std::function`s implementation too. And yes, it's a pointer, all pointers are "views" right? : D – KeyC0de Sep 21 '19 at 22:31
  • @Nikos Yep. But the real `std::function` is a bit different and is not really a function pointer kind of thing. – Lightness Races in Orbit Sep 22 '19 at 13:35
  • Yes. Regarding your previous comment.. Are you maybe aware of a way to make it compatible with member functions/functors? I'm thinking of type erasure through template, ie. a virtual function call (this is what `std::function` does I believe).. – KeyC0de Sep 22 '19 at 14:02
  • @Nikos Just bind a lambda to it and let the lambda capture do the hard work – Lightness Races in Orbit Sep 22 '19 at 14:02
  • Yes indeed that works. Although not as a universal solution as `std::function`. – KeyC0de Sep 22 '19 at 14:03
  • @Nikos You shouldn't use `std::function` as a replacement for generic callables anyway – Lightness Races in Orbit Sep 22 '19 at 14:06
2

R(*pf)(void*, Args...) is a function pointer (regular one, not pointer-to-member) to a function that returns R and has (void*, Args...) parameters, where Args... is a list of types (an expanded template parameter pack).

Maybe this void* represents this* and its another way to define a member pointer variable

Nah, there is no such feature in C++.

If you look at the code, the only things assigned to this pointer are lambdas, like this one:

pf = [](void* ptr, Args... args)->R{
  return blah;
};

I'm not sure why you expected pointers-to-members to be involved.

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207