【问题标题】:How to pass a function in a parameter and then call that function from an object如何在参数中传递函数,然后从对象调用该函数
【发布时间】:2015-01-11 21:29:29
【问题描述】:

我有一个 Sprite 类,它有一个 int update(int key) 方法。

我还有另一个类 (SpriteManager),其中包含所有 Sprites 的列表。我想向这个类添加一个方法,该方法接受一个方法,并将一个 int 作为参数。然后我想遍历这个列表并在所有对象上调用该方法。但是,我找不到任何方法来做到这一点。我知道如何将函数作为参数传递,也知道如何在上下文之外调用对象的特定方法,但我不知道如何做到这两点。

使用此方法的示例如下:

sm.tellSpritesToDoSomething(Sprite::update, 42);

其中smSpriteManager

【问题讨论】:

  • 你有 3 个选项:::std::function、::std::bind 和模板,随你喜欢。
  • 你知道哪个最快吗?
  • 通常是模板方法,因为它最简单。
  • 如何使用模板?

标签: c++ function syntax


【解决方案1】:

您应该检查std::bindstd::functionplaceholders。并且永远记住,方法本身是不够的,你需要在里面传递将用作 this 的对象。例如

sm.tellSpritesToDoSomething(std::bind(&Sprite::update, _1, 42));

其他方法是使用成员函数指针(显式或通过模板):

#include <vector>
#include <algorithm>
#include <functional>

struct Sprite {
    int update(int i) { return i; }
};

struct SpriteManager {
    std::vector<Sprite> sprites;
    template <typename F>
    void tellSpritesToDoSomething(F f, int i) {
        for (auto& sprite: sprites)
        {
            (sprite.*f)(i);
        }
    }
    void tellSpritesToDoSomething2(int (Sprite::*f)(int), int i) {
        for (auto& sprite: sprites)
        {
            (sprite.*f)(i);
        }
    }
    void tellSpritesToDoSomething3(std::function<int(Sprite&)> f) {
        std::for_each(sprites.begin(), sprites.end(), f);
    }
};

int main() {
    SpriteManager sm;
    sm.sprites.emplace_back();
    sm.sprites.emplace_back();
    sm.sprites.emplace_back();
    sm.tellSpritesToDoSomething(&Sprite::update, 42);
    sm.tellSpritesToDoSomething2(&Sprite::update, 42);
    using std::placeholders::_1;
    sm.tellSpritesToDoSomething3(std::bind(&Sprite::update, _1, 42));
}

【讨论】:

  • 这些方法快吗?我可能必须每秒调用这些方法数百次,我希望它尽可能流畅。
  • 每秒数百次对于大多数桌面/服务器 cpu 来说是非常低的数字。从这个开始,只有当你可以用分析器证明这是你的瓶颈时,才考虑更快的替代方案。
  • 好的,谢谢。上面的一位用户(他回答了我的问题)提到了使用模板。你知道我该怎么做吗?
  • @KhanPower 第一个是使用模板。您还可以将模板方法与std::for_each 方法结合使用。模板方法可能会稍微快一点,但编译起来会稍微慢一些(它可能必须放在头文件中)。
  • @TomaszKłak 当您知道您的参数将是什么类型时,您不需要模板。我设想它们可以获取 lambda 对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-31
  • 2022-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多