我一直在努力解决这个问题。请考虑以下代码(我假设前向引用已定义):
filtered_csv['expression'] = filtered_csv['expression'].replace(emotion_map)
鉴于上述情况,构造函数可以执行以下操作:
// Signature representing a pointer to a method call
typedef
void (MyClass::*MyMethod)(int);
class MyClass
{
MyClass();
void method1(int i);
void method2(int i);
void associateMethod(int index, MyMethod m);
}
但是,我希望能够调用“关联方法”。其中第二个参数是匿名方法。但是,以下内容无法编译。
MyClass::MyClass()
{
associateMethod(1, &MyClass::method1);
associateMethod(2, &MyClass::method2);
}
我得到一个关于他们没有从lambda到MyMethod的可行转换的错误。
我想知道lambda语法是否需要包含' MyClass'在某处,但随机猜测lambda表达式,如
associateMethod(3, [this](int) -> void { /* some code here */ }
或
MyClass::[this](int) -> void {}
不要编译。
会欣赏任何指针(没有双关语)
由于
答案 0 :(得分:5)
你不能将lambda表达式转换为类成员函数指针,并且没有有效的语法使它看起来像一个 1 。
您应该将MyMethod
声明为std::function
签名(如评论中所述),而不是原始函数指针:
using MyMethod = std::function<void(int)>;
然后您可以使用lambdas初始化此参数:
MyClass::MyClass()
{
associateMethod(1, [this](int a) { this->method1(a); });
associateMethod(2, [this](int a) { this->method2(a); });
}
1) Lambda函数可以被认为是编译器生成的可调用类,它将捕获作为构造参数,并为您指定的参数和主体提供operator()()
重载。因此,没有可能有效转换为原始或成员函数指针。
答案 1 :(得分:1)
user0042 的回答似乎要走了,但是,为了完整起见,值得一提的是,在C ++中17无捕获的lambdas有一个 constexpr 转换运算符到它们的函数指针类型,因此你应该(*)能够通过类似的方式将这样的lambda转换为成员函数指针:
// ...
void associateMethod(int index, MyMethod m);
template<typename F>
void associateMethod(int index, F m) {
associateMethod( index,
static_cast<MyMethod>(
&MyClass::bindFun< static_cast<void(*)(MyClass*,int)>(m) >
) );
}
private:
template<auto F>
void bindFun(int x){ (*F)(this,x); }
// to be used like
x.associateMethod(0,[](MyClass* this_, int x){ this_->method1(x+1); });
(*)遗憾的是,这是用clang编译的,但gcc拒绝编译它(我会问这个问题,你可以找到它here)。