Здравствуйте, rg45, Вы писали:
R>Хотя, казалось бы, чего уж проще:
R>https://godbolt.org/z/1aEEdoE96
R>R>#include <stdio.h>
R>template <auto member>
R>requires (member != nullptr)
R>struct Accessor
R>{
R> constexpr decltype(auto) operator()(auto&& object) const {
R> return object.*member;
R> }
R> constexpr decltype(auto) operator()(auto&& object, auto&&...args) const {
R> return (object.*member)(args...);
R> }
R>};
R>template <auto member> constexpr Accessor<member> accessor;
R>struct A {
R> int x = 10;
R> virtual int fn(int y) { return x + y; }
R>};
R>int main() {
R> A a[1];
R> auto fn = accessor<&A::fn>;
R> auto x = accessor<&A::x>;
R> printf("x=%d fn(20)=%d\n", x(*a), fn(*a, 20));
R>}
R>
Это конечно здорово, но это просто обёртка. Она не решает вопроса как такое передавать во внешнюю среду, или принимать из неё подобное.
struct A {
int x=10;
virtual int fn(int y) { return x+y; }
static int* ptr_to_x(A* a) { return &a->x; }
static int (ptr_to_fn)(A* a,int y) { return a->fn(y); }
};
#include <stdio.h>
int main(int argc, char **argv) {
A a[1];
int (*pfn)(A*,int)=A::ptr_to_fn;
int* (*px)(A*)=A::ptr_to_x;
printf("px=%p pfn=%p\n",px,pfn);
printf("x=%d fn(20)=%d\n",*px(a),pfn(a,20));
return 0;
}
Более того предыдущие указатели можно было сгенерировать руками если нет поддержки c++17. А тут только C++20.
ps: А что будет если надо обернуть функцию без параметров void A::g(); ?