[英]How do I write a lambda expression that looks like a method?
I've been going nuts trying to figure this out. 我一直在努力解决这个问题。 Consider the following code (I'm assuming forward references have been defined): 考虑下面的代码(我假设已经定义了前向引用):
// 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);
}
Given the above, the constructor can do things like the following: 鉴于以上所述,构造函数可以执行以下操作:
MyClass::MyClass()
{
associateMethod(1, &MyClass::method1);
associateMethod(2, &MyClass::method2);
}
However, I'd like to be able to invoke 'associateMethod' where the second parameter is an anonymous method. 但是,我希望能够在第二个参数是匿名方法的情况下调用“ associateMethod”。 However, the following doesn't compile. 但是,以下内容无法编译。
associateMethod(3, [this](int) -> void { /* some code here */ }
I get an error about their being no viable conversion from the lambda to MyMethod. 我收到一个错误消息,说它们无法从lambda转换为MyMethod。
I'm wondering if the lambda syntax needs to include 'MyClass' somewhere but random guesses for the lambda expression such as 我想知道lambda语法是否需要在某个地方包含“ MyClass”,但会随机猜测lambda表达式,例如
MyClass::[this](int) -> void {}
or 要么
[this]&MyClass::(int) -> void {}
don't compile. 不要编译。
Would appreciate any pointers (no pun intended) 将不胜感激任何指针(无双关语)
Thanks 谢谢
You can't convert a lambda expression to a class member function pointer and there's no valid syntax to make it look like one 1 . 您不能将lambda表达式转换为类成员函数指针,并且没有有效的语法使其看起来像1 。
Instead of a raw function pointer, you should declare the MyMethod
as std::function
signature (as was mentioned in the comments): 而不是原始的函数指针,应将MyMethod
声明为std::function
签名(如注释中所述):
using MyMethod = std::function<void(int)>;
You can use lambdas then to initialize this parameter then: 然后可以使用lambdas初始化此参数,然后:
MyClass::MyClass()
{
associateMethod(1, [this](int a) { this->method1(a); });
associateMethod(2, [this](int a) { this->method2(a); });
}
1) Lambda functions can be thought as compiler generated callable classes, which take the captures as parameters on construction and provide a operator()()
overload with the parameters and body you specify. 1) Lambda函数可以视为编译器生成的可调用类,该类将捕获作为构造时的参数,并为operator()()
重载您指定的参数和主体。 Hence there's no possible valid conversion to a raw or member function pointer. 因此,不可能有效转换为原始或成员函数指针。
user0042 's answer seems the way to go but, just for completeness sake, it's worth mentioning that in C++17 captureless lambdas have a constexpr conversion operator to their function pointer type, hence you should(*) be able of converting such a lambda to a member function pointer, via something like: user0042的答案似乎是解决之道,但是,出于完整性考虑,值得一提的是,在C ++ 17中,无捕获lambda具有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); });
(*) sadly, this compiles in clang but gcc refuses to compile it (I'm going to ask a question about this, you can find it here ). (*)可悲的是,这是用clang编译的,但是gcc拒绝编译它(我要问一个问题,您可以在这里找到它)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.