如何编写看起来像方法的lambda表达式?

时间:2017-12-02 04:32:26

标签: c++ methods lambda syntax

我一直在努力解决这个问题。请考虑以下代码(我假设前向引用已定义):

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 {}

不要编译。

会欣赏任何指针(没有双关语)

由于

2 个答案:

答案 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)。