是否存在函数指针未涵盖的std :: function的用例,还是仅仅是语法糖?

sta*_*tti 12 c++ c++-standard-library c++11 std-function

与函数指针相比​​,std :: function的表示法非常好.但是,除此之外,我找不到一个用指针无法替换的用例.那么它只是函数指针的语法糖吗?

And*_*owl 26

std::function<>使您可以封装任何类型的可调用对象,这是函数指针无法做到的事情(尽管非捕获 lambda可以转换为函数指针).

为了让您了解它可以实现的灵活性:

#include <functional>
#include <iostream>
#include <vector>

// A functor... (could even have state!)
struct X
{
    void operator () () { std::cout << "Functor!" << std::endl; }
};

// A regular function...
void bar()
{
    std::cout << "Function" << std::endl;
}

// A regular function with one argument that will be bound...
void foo(int x)
{
    std::cout << "Bound Function " << x << "!" << std::endl;
}

int main()
{
    // Heterogenous collection of callable objects
    std::vector<std::function<void()>> functions;

    // Fill in the container...
    functions.push_back(X());
    functions.push_back(bar);
    functions.push_back(std::bind(foo, 42));

    // And a add a lambda defined in-place as well...
    functions.push_back([] () { std::cout << "Lambda!" << std::endl; });

    // Now call them all!
    for (auto& f : functions)
    {
        f(); // Same interface for all kinds of callable object...
    }
}
Run Code Online (Sandbox Code Playgroud)

像往常一样,请看这里的实例.除此之外,这允许您实现命令模式.


Jos*_*eld 7

std::function旨在表示任何类型的可调用对象.有许多可调用的对象无法通过函数指针以任何方式表示.

  1. 一个仿函数:

    struct foo {
      bool operator()(int x) { return x > 5; }
    };
    
    bool (*f1)(int) = foo(); // Error
    std::function<bool(int)> f2 = foo(); // Okay
    
    Run Code Online (Sandbox Code Playgroud)

    您无法创建实例foo并将其存储在bool(*)(int)函数指针中.

  2. 带有lambda捕获lambda:

    bool (*f1)(int) = [&](int x) { return x > y; }; // Error
    std::function<bool(int)> f2 = [&](int x) { return x > y; }; // Okay
    
    Run Code Online (Sandbox Code Playgroud)

    但是,没有捕获的lambda可以转换为函数指针:

    没有lambda-capture的lambda表达式的闭包类型有一个公共的非虚拟非显式const转换函数,用于指向具有与闭包类型的函数调用操作符相同的参数和返回类型的函数.此转换函数返回的值应为函数的地址,该函数在调用时与调用闭包类型的函数调用运算符具有相同的效果.

  3. 实现定义的可调用返回值:

    bool foo(int x, int y) { return x > y; };
    
    bool (*f1)(int) = std::bind(&foo, std::placeholders::_1, 5); // Error (probably)
    std::function<bool(int)> f2 = std::bind(&foo, std::placeholders::_1, 5); // Okay
    
    Run Code Online (Sandbox Code Playgroud)

    std::bind返回值是一个实现定义的可调用对象.只能使用该对象的方式由标准指定,而不是其类型.