C++ 单表达式成员函数指针

C++ 单表达式成员函数指针,c++,c++20,C++,C++20,对于类的特定实例,表示成员函数指针的标准方法是使用实例指针和成员函数指针: void Execute(Foo* inst, void (Foo::*func)(int), int x) { (inst->*func)(x); } ... Execute(foo, &Foo::Bar, 42); 有没有办法定义Execute,使函数指针表示为单个表达式? 例如: void Execute(SomeType v, int x) { (v.inst->*v.func)(x

对于类的特定实例,表示成员函数指针的标准方法是使用实例指针和成员函数指针:

void Execute(Foo* inst, void (Foo::*func)(int), int x) {
  (inst->*func)(x);
}
...
Execute(foo, &Foo::Bar, 42);
有没有办法定义Execute,使函数指针表示为单个表达式?

例如:

void Execute(SomeType v, int x) {
  (v.inst->*v.func)(x);
}
...
Execute(foo->Bar, 42);
我的主要问题是,在我的特定情况下,
Foo
嵌套在一个长而不稳定的名称空间链下,因此使用标准语法的实际调用看起来更像
Execute(Foo,&hello::dark::My::old::friend::Foo::Bar,42)
。然而,我几乎总是有一个本地
foo
实例,从中我可以参考更简单的
foo->Bar(42)
。不过,我需要做一些额外的簿记,这就是为什么我需要将调用包装为类似
Execute
的内容<遗憾的是,代码>使用指令和命名空间别名不是一个选项

有没有办法定义Execute,使函数指针表示为单个表达式

对。将函数更改为使用
std::function
或可调用的模板参数,例如:

#包括
void执行(std::函数v,int x)
{
v(x);
}
模板
void Execute(可调用的v,int x)
{
v(x);
}
然后可以使用
std::bind()
或lambda作为输入表达式,例如:

#包括
使用名称空间std::占位符;
使用FooType=std::remove\u reference::type;
执行(std::bind(&FooType::Bar,foo,_1),42);
//或者,在C++20及更高版本中:
执行(std::bind_front(&FooType::Bar,foo),42);
Execute([=](intx){foo->Bar(x);},42);

另外,在C++Builder中,有一个
\u closure
扩展,允许调用成员方法,而不必限定类类型,例如:

typedef void(u闭包*TExecuteCallable)(int);
void Execute(TExecuteCallable v,int x)
{
v(x);
}
...
执行(foo->Bar,42);
//或
执行(&(foo->Bar),42);

作为一个成员指针,不是。但您可以轻松编写一个绑定成员的类型functions@Human-编译器是正确的,但是我不能在特定的实例上调用它。它还需要拼写出整个名称空间。或者你是说可以把
foo->Bar
翻译成
&你好::黑暗…::foo::Bar
?再读一遍,我可能误解了这个问题。如果您希望在尝试访问成员指针时避免键入类型的全名,您可能需要使用
别名来缩短它,或者最好使用
&decltype(foo)::Bar
来避免完全限定的名称我不确定这是否真的可行,但是你会喜欢像
Execute(foo,Bar,42)这样的东西吗
?@Human编译器我想我可以使用一些
decltype
magic,但它最终需要看起来像
&std::remove\u reference::type::Bar
,这仍然很恶心。有没有一种方法可以在实现中隐藏这个问题(不使用宏)?小注:C++20有
std::bind_-front
,它比重量级工具更可取,即
std::bind_-front(&FooType::Bar,foo)
,尽管这回答了标题中的问题,这似乎并没有解决本文其余部分和注释中详细说明的实际问题——在获取成员函数指针时,似乎不希望完全限定类型名。@真的吗?带有
decltype
FooType
别名不能解决这个问题?或者事实上兰姆达完全不需要这样做?我想我一开始一定是误读了你的答案;不需要防守。我没有发现
FooType
是一个别名,我错误地理解了lambda仍然在使用成员函数。我的错@克里斯补充道,谢谢。尽管如此,lambda通常比任何
std::bind…()