【问题标题】:std::function template syntaxstd::function 模板语法
【发布时间】:2016-05-03 06:15:16
【问题描述】:

我对 std::function 很熟悉,但我正在读一本书,里面有这样的代码:

template<typename GameObject, typename Function>
std::function<void(SceneNode&, sf::Time)> derivedAction(Function fn)
{
    return [=](SceneNode& node, sf::Time dt)
    {
        assert(dynamic_cast<GameObject *>(&node) != nullptr);

        fn(static_cast<GameObject *>(&node), dt)
    }
}

然后本书使用这样的模板:

Command moveLeft;//command is a structure
moveLeft.action//action is a std::function object 
= derivedAction<Aircraft>(AircraftMover(-playerSpeed, 0));
//derivedAction specify<Aircraft> ??? 

我的问题是:

1-derivedAction 必须是 std::function 的对象,我已经检查了引用,但我没有发现这种使用 {} 的初始化,这是如何工作的?

2-理解 lambda 表达式对我来说很复杂,为什么要返回它?

我对这段代码很困惑,任何解释都将不胜感激

【问题讨论】:

    标签: c++11 lambda std-function


    【解决方案1】:

    std::function 是可以调用的任何东西的包装器(即,您可以在其上使用operator())。那是指向函数、具有operator() 重载的类或 lambda 表达式的指针。

    在您的情况下,derivedAction 是一个模板函数,接受单个参数(名称为 Function 的模板类型)并返回一个具有 void 返回类型的函数并接受两个参数——SceneNode&amp; 和 @ 987654330@.

    所以回答你的问题。

    1-derivedAction 必须是 std::function 的对象,我已经检查了引用,但我没有发现这种使用 {} 的初始化,这是如何工作的?

    不,derivedAction 本身就是一个函数,就像任何其他函数一样(即int foo(){ return 0; })。

    2-理解 lambda 表达式对我来说很复杂,为什么要返回它?

    再一次,derivedAction 的返回值是一个函数(或者更确切地说,是可调用的东西)。

    如果您仔细查看derivedAction 的代码,您会发现它只包装了一个带有一些检查的函数Function fn

    【讨论】:

    • 另一个问题:如果 Gameobject typename 在 Function typename 之前,并且我们在调用 derivedAction 时使用相同的语法,我们会出现编译错误?
    • 所以派生函数将整个 lambda 表达式作为 std::function 返回?
    • @shayan 如果你切换这两个typenames,它不会导致定义中的编译器错误。但是,它会在调用derivedAction 时产生编译器错误,因为template argument deduction 将失败。
    • @shayan 是的,derivedAction 的返回 value 就是那个 lambda 表达式。
    【解决方案2】:

    对于您的第一个问题,derivedAction 是一个函数,因此您可以像定义任何其他函数一样定义一个空主体 {}

    至于你的第二个问题,returnderivedAction 的返回。 lambda的细分如下:

    • [=] 指示通过复制来捕获任何引用的变量
    • (SceneNode&amp; node, sf::Time dt) 描述了 lambda 函数的输入参数
    • 在 lambda 的主体中,lambda 函数在 fn() 上运行。它将node 转换为不同的类型并修改node 对象。

    在您的示例中,fnAircraftMover(-playerSpeed, 0)。 playerSpeed 是SceneNode&amp; 类型,0 是sf::Time 类型。该函数的返回类型是void。所以,这一切最终所做的就是根据dt 修改你输入的playerSpeed。希望这是有道理的..!

    【讨论】:

      猜你喜欢
      • 2015-02-20
      • 2013-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-03
      相关资源
      最近更新 更多