繁体   English   中英

std :: function vs Lambda用于传递成员函数

[英]std::function vs Lambda for passing member functions

我正在为游戏引擎创建消息传递系统,其中引擎的最终用户可以创建消息对象并将其传递给游戏对象,以由包含附加到游戏对象的组件的侦听器对象进行解释。 如果消息与侦听器正在侦听的消息匹配,则侦听器应调用函数指针并将其传递给已接收的消息。 基本结构看起来像这样:

class Message
{
    std::string message;
};

class Listener
{
    std::string target;
    void (*fn)(Message*);
};

使用游戏对象的代码来接收如下所示的消息:

//if the queue is empty then dont do anything
if (messageQueue.empty())
{
    return;
}

//else grab the front of the queue
Message* newMessage = messageQueue.front();

//pop our message from the queue
messageQueue.pop();

//for each component in our list
for (std::vector<Component*>::iterator i = ComponentList.begin(); i < ComponentList.end(); i++)
{
    Component* itemp = *i;
    //for each message in its listener list
    for (std::vector<Listener*>::iterator j = itemp->Listeners.begin(); j < itemp->Listeners.end(); j++)
    {
        Listener* jtemp = *j;
        //check the listener against the newMessage
        if (jtemp->name == newMessage->name)
        {
            //call jtemp's function
            jtemp->function(newMessage);
        }
    }
}

我遇到的问题是,由于上面的代码片段需要调用的函数是组件类型的成员函数,我不能将Listener.fn设置为等于Component::foo或任何其他函数。

我问我的同学,看看他们是否可以提供任何建议,我收到的两条建议是使用lambdas或使用std::function将成员函数指针转换为常规函数指针。

我之前从未使用过lambda函数,但是在这里研究之后,如果我正确地把握它,似乎每次我传递一条消息时都会写一个新的lambda,这会破坏使用像这样的系统的目的。 和研究后std::function 在这里在这里 ,并在这里好像std::function会给我我需要的灵活性,但实现已经给了我大量错误的

我是否可以忽略lambdas的强大std::function在这种情况下我是否应该使用std::function ,如果是这样,如何创建一个返回void并获取消息指针的std::function

std::function是正确的存储解决方案。 std::function几乎存储了与其签名兼容的任何内容。

通常你会用lambda填充它。 因为这比bind或其他替代方法更容易和更清晰。

std::function<void(Message*)> fn;

fn = [comp](Message * m){ comp->foo(m); };

根据我的经验,如果您可以访问C ++ 11,请忘记“经典”函数指针。 在C ++中编写指向成员函数的指针很复杂。 语法不直观,可导致脱发:/

正如Yakk所说, std::function几乎适用于任何情况。 Lambda表达式虽然语法上很笨拙( lambda capture ),但非常有用。 将它们与std::function结合使用,你可以实现你想要的任何东西x)

如果你仍然想使用经典函数指针,我建议你阅读这个帖子(这个网站一般用于围绕C ++的其他目的):
https://isocpp.org/wiki/faq/pointers-to-members#fnptr-vs-memfnptr-types

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM