简体   繁体   English

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

[英]How to capture function arguments and store function pointer for later execution in C++11?

My requirement is to store some functions for later execution with pre-defined arguments.我的要求是使用预定义的参数存储一些函数供以后执行。 Here is what I have tried这是我尝试过的

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]();
}

However this does not compile and gives following error但是这不会编译并给出以下错误

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]();
    ^~~~~~~~~~~~~~~~~

How can I achieve this in C++11/14 ?我怎样才能在C++11/14实现这一点?

After binding the arguments to the function, the call doesn't take any further arguments anymore.将参数绑定到函数后,调用不再接受任何进一步的参数。 Therefore the function type should be void() :因此函数类型应该是void()

std::vector<std::function<void()>> functionVector;

Also note that you can use lambdas in C++11 and later, which are more flexible than std::bind :另请注意,您可以在 C++11 及更高版本中使用 lambda,它们比std::bind更灵活:

functionVector.push_back([](){ doSomething(1, 2); });
functionVector.push_back([](){ doSomething(4, 2); });

or slightly simplified, empty parameter lists can be omitted:或者稍微简化,可以省略空参数列表:

functionVector.push_back([]{ doSomething(1, 2); });
functionVector.push_back([]{ doSomething(4, 2); });

As you can see the lambdas don't have any parameters here and so the type of their call operators is void() .正如您所看到的,这里的 lambda 表达式没有任何参数,因此它们的调用运算符的类型是void()


Although it won't make any real difference, I would also suggest you to use emplace_back (since C++11) instead of push_back .虽然它不会产生任何真正的区别,但我也建议您使用emplace_back (C++11 起)而不是push_back

push_back expects a reference to the element type (here std::function<void()> ), but since you are passing it something else, the std::function<void()> will first be constructed as a temporary for the push_back parameter and then the vector element with be move-constructed from it. push_back需要对元素类型的引用(此处为std::function<void()> ),但由于您将其他内容传递给它,因此std::function<void()>将首先构造为push_back的临时对象参数,然后从它移动构造向量元素。

emplace_back on the other hand expects the constructor arguments for the vector element and will construct the std::function<void()> object directly in-place without intermediate temporary.另一方面, emplace_back需要向量元素的构造函数参数,并将直接就地构造std::function<void()>对象,无需中间临时。


In this specific instance std::function is also unnecessary when using lambdas, since lambdas without capture decay to function pointers, which you can store as a lightweight alternative to std::function :在此特定实例中,使用 lambda 时也不需要std::function ,因为 lambda 没有捕获衰减到函数指针,您可以将其存储为std::function的轻量级替代品:

std::vector<void(*)()> functionVector;

If you intend to store lambdas with capture, then the std::function approach is required.如果您打算使用捕获存储 lambda,则需要使用std::function方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM