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

问题描述 投票:2回答:1

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

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

但是它无法编译并给出以下错误

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

如何在C++11/14中实现?

c++ c++11 c++14 function-pointers
1个回答
6
投票

将参数绑定到函数后,该调用将不再接受任何其他参数。因此,函数类型应为void()

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

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

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

或略作简化的空参数列表可以省略:

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

您可以看到lambda在这里没有任何参数,因此它们的调用运算符的类型为void()


尽管虽然没有任何实际的区别,但我也建议您使用emplace_back(因为C ++ 11)而不是push_back

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

[emplace_back另一方面期望vector元素的构造函数参数,并且将直接在原位构造std::function<void()>对象,而没有中间临时对象。


在此特定情况下,使用lambda时也不需要std::function,因为没有捕获的lambda会衰减到函数指针,您可以将其存储为std::function的轻量级替代品:

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

如果您打算存储带有捕获的lambda,则需要std::function方法。

© www.soinside.com 2019 - 2024. All rights reserved.