如何捕获函数参数并存储函数指针以供以后在 C++11 中执行?

Abh*_*sal 2 c++ function-pointers c++11 c++14

我的要求是使用预定义的参数存储一些函数供以后执行。这是我尝试过的

void doSomething(int i, int j) {
    std::cout << "Sum " <<  i + j << std::endl;
}

int main(int argc, char *argv[]) {
    std::vector<std::function<void(int, int)>> functionVector;

    functionVector.push_back(std::bind(doSomething, 1, 2));
    functionVector.push_back(std::bind(doSomething, 4, 2));

    functionVector[0]();
    functionVector[1]();
}
Run Code Online (Sandbox Code Playgroud)

但是这不会编译并给出以下错误

error: no matching function for call to object of type 'std::__1::__vector_base<std::__1::function<void (int, int)>,
      std::__1::allocator<std::__1::function<void (int, int)> > >::value_type' (aka 'std::__1::function<void (int, int)>')
    functionVector[0]();
    ^~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点C++11/14

wal*_*nut 6

将参数绑定到函数后,调用不再接受任何进一步的参数。因此函数类型应该是void()

std::vector<std::function<void()>> functionVector;
Run Code Online (Sandbox Code Playgroud)

另请注意,您可以在 C++11 及更高版本中使用 lambda,它们比std::bind以下更灵活:

functionVector.push_back([](){ doSomething(1, 2); });
functionVector.push_back([](){ doSomething(4, 2); });
Run Code Online (Sandbox Code Playgroud)

或者稍微简化,可以省略空参数列表:

functionVector.push_back([]{ doSomething(1, 2); });
functionVector.push_back([]{ doSomething(4, 2); });
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,这里的 lambda 表达式没有任何参数,因此它们的调用运算符的类型是void().


虽然它不会产生任何真正的区别,但我也建议您使用emplace_back(自 C++11 起)而不是push_back.

push_back期望对元素类型的引用(此处std::function<void()>),但由于您正在传递其他内容,因此std::function<void()>将首先构造为push_back参数的临时元素,然后从中移动构造向量元素。

emplace_back另一方面,期望向量元素的构造函数参数,并将std::function<void()>直接就地构造对象,无需中间临时。


在这个特定的例子std::function中,当使用 lambdas 时也是不必要的,因为 lambdas 没有捕获衰减到函数指针,您可以将其存储为轻量级替代std::function

std::vector<void(*)()> functionVector;
Run Code Online (Sandbox Code Playgroud)

如果您打算使用捕获存储 lambda,则std::function需要该方法。