C++ 11 Lambda函数内部成员方法继承范围

jed*_*rds 7 c++ lambda member-functions c++11

我编写了一个foreach接受lambda函数ala的函数:

void foreach(void (*p)(pNode))
{ /* ... */ }
Run Code Online (Sandbox Code Playgroud)

如果我从主循环传递lambda函数,它的工作原理如下:

int a = 5;
env.N().foreach
(
    [&](pNode n)->void
    {
        n->tps(a); 
    }
);
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试从成员方法中调用相同的函数,则lambda函数"继承"成员函数的范围并生成编译器错误.例如,如果我尝试将其包含在Object名为的类的成员方法中method(),我会收到以下错误:

error: no matching function for call to ‘IDSet<Node>::foreach(Object::method()::<lambda(pNode)>)’
note: candidate is: void IDSet<T>::foreach(void (*)(IDSet<T>::pT)) [with T = Node, IDSet<T>::pT = pNode]
Run Code Online (Sandbox Code Playgroud)

我意识到这是编译器是安全的,因为我可以在lambda函数中包含特定于实例的变量,在这种情况下lambda需要作用域,但是我想知道是否可以使这个lambda"静态".

我试过了reinterpret_cast,但是这给了我这个错误:

error: invalid cast from type ‘Object::method()::<lambda(pNode)>’ to type ‘void (*)(pNode)’
Run Code Online (Sandbox Code Playgroud)

static之前指定[&](pNode ...似乎也不是有效的语法.

拼命,我也试着更改[&][=],[],[a],其中没有工作.

有没有人知道是否有办法完成我创建"静态"lambda函数的目标,或者是否可以接受任何类型的lambda函数?

谢谢!


回答:

Cat Plus Plus的帮助下,我能够转换错误的代码:

void foreach(void (*p)(pT))
{
    for(pTiter i = _map.begin(); i != _map.end(); i++)
    {
        (*p)(i->second);
    }
}
Run Code Online (Sandbox Code Playgroud)

进入功能齐全的代码:

void foreach(std::function<void(pT)>(p))
{
    for(pTiter i = _map.begin(); i != _map.end(); i++)
    {
        p(i->second);
    }
}
Run Code Online (Sandbox Code Playgroud)

这完全符合我的要求.

Cat*_*lus 8

好吧,你不能使用指针.

void foreach(std::function<void(pNode)>);
Run Code Online (Sandbox Code Playgroud)

  • 请注意,根据FDIS,无捕获的lambda可隐式转换为函数指针.也就是说,OP的代码对于无捕获(`[]`)lambda应该没问题. (3认同)