首页 文章

std :: function <>和标准函数指针之间的区别? [重复]

提问于
浏览
54

这个问题在这里已有答案:

什么是std :: function <>和标准函数指针之间的区别?

那是:

typedef std::function<int(int)> FUNCTION;
typedef int (*fn)(int);

它们实际上是一回事吗?

4 回答

  • 39

    函数指针是C中定义的实际函数的地址 . std::function 是一个包装器,可以容纳任何类型的可调用对象(可以像函数一样使用的对象) .

    struct FooFunctor
    {
        void operator()(int i) {
            std::cout << i;
        }
    };
    
    // Since `FooFunctor` defines `operator()`, it can be used as a function
    FooFunctor func;
    std::function<void (int)> f(func);
    

    在这里, std::function 允许你抽象出你正在处理的是什么类型的可调用对象 - 你只知道它返回 void 并且有一个 int 参数 .

    这个抽象很有用的一个真实例子就是当你将C与另一种脚本语言结合使用时 . 您可能希望设计一个接口,该接口可以通用方式处理C中定义的函数以及脚本语言中定义的函数 .

    Edit: 绑定

    除了 std::function ,您还可以找到 std::bind . 这两个是一起使用时非常强大的工具 .

    void func(int a, int b) {
        // Do something important
    }
    
    // Consider the case when you want one of the parameters of `func` to be fixed
    // You can used `std::bind` to set a fixed value for a parameter; `bind` will
    // return a function-like object that you can place inside of `std::function`.
    
    std::function<void (int)> f = std::bind(func, _1, 5);
    

    在该示例中, bind 返回的函数对象接受第一个参数 _1 ,并将其作为 a 参数传递给 func ,并将 b 设置为常量 5 .

  • 4

    它们完全不一样 . std::function 是一个复杂,沉重,有状态,近乎魔法的类型,可以容纳任何类型的可调用实体,而函数指针实际上只是一个简单的指针 . 如果你能逃脱它,你应该更喜欢裸函数指针或 auto - bind / auto -lambda类型 . 如果你真的需要一种系统的方法来组织可调用实体的异构集合,例如函数,函子,捕获lambdas和绑定表达式,那么只使用 std::function .


    更新:关于 auto 类型的一些解释:比较以下两个函数:

    void do_something_1(std::function<void(int)> f, int a) { f(a); }
    
    template <typename F, typename A> void do_something_2(F f, A a) { f(a); }
    

    现在想象一下用lambda或 bind 表达式调用它们:

    do_something_X([foo, &bar](int n){ bar += n*foo; },     12);
    do_something_X(std::bind(X::bob, &jim, true, _1, Blue), 13);
    

    带有模板的第二个版本更有效,因为在这两种情况下,参数 F 都被推导为表达式的实际不可知类型 . 带有 std::function 的第一个版本不是模板,可能看起来更简单,更有意思,但它总是强制构造 std::function 对象,并且很可能带有多种类型的擦除和虚拟调度成本 .

  • 42

    std::function 有州 . 它可以包含其他参数"bound" .

    这些参数的范围可以是其他类,其他函数,甚至是成员函数调用的指针 .

    替换函数指针不是 typedef int (*fn)(int);

    它是 typedef int (*fn)(void*,int);void* 重新排列将隐藏在 std::function 中的状态 .

  • 11

    没有 .

    一个是函数指针;另一个是一个对象,用作函数指针的包装器 .

    它们几乎代表相同的东西,但 std::function 更强大,允许你做绑定和诸如此类的东西 .

相关问题