我想知道是否有可能只用一条指令而不是 lambda 来调用容器中的回调(这是一种练习)。
我尝试了std::invoke
。这是我的代码:
#include <algorithm>
#include <functional>
#include <iostream>
int main()
{
std::function<void(void)> foo = []() { std::cout << "Foo !"; };
std::function<void(void)> bar = []() { std::cout << "Bar !"; };
const std::vector<std::function<void(void)>> callbacks = { foo, bar };
std::for_each(callbacks.cbegin(), callbacks.cend(), std::invoke);
return 0;
}
但我在编译时遇到很多错误:
main.cpp: In function ‘int main()’:
main.cpp:12:22: error: no matching function for call to ‘for_each(std::vector >::const_iterator, std::vector >::const_iterator, )’
12 | std::for_each(callbacks.cbegin(), callbacks.cend(), std::invoke);
| ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/11/algorithm:62,
from main.cpp:1:
/usr/include/c++/11/bits/stl_algo.h:3814:5: note: candidate: ‘template _Funct std::for_each(_IIter, _IIter, _Funct)’
3814 | for_each(_InputIterator __first, _InputIterator __last, _Function __f)
| ^~~~~~~~
/usr/include/c++/11/bits/stl_algo.h:3814:5: note: template argument deduction/substitution failed:
main.cpp:12:22: note: couldn’t deduce template parameter ‘_Funct’
12 | std::for_each(callbacks.cbegin(), callbacks.cend(), std::invoke);
| ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/11/algorithm:74,
from main.cpp:1:
/usr/include/c++/11/pstl/glue_algorithm_defs.h:42:1: note: candidate: ‘template __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, void> std::for_each(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Function)’
42 | for_each(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Function __f);
| ^~~~~~~~
/usr/include/c++/11/pstl/glue_algorithm_defs.h:42:1: note: template argument deduction/substitution failed:
main.cpp:12:22: note: candidate expects 4 arguments, 3 provided
12 | std::for_each(callbacks.cbegin(), callbacks.cend(), std::invoke);
| ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Call Stack
# Function File:Line
Local Variables
Variable Value
Registers
Register Value
Display Expressions
Expression Value
Breakpoints and Watchpoints
# Description
我也尝试过这样的方式:
std::for_each(callbacks.cbegin(), callbacks.cend(), std::invoke<void(void)>);
但我仍然有问题:
In file included from /usr/include/c++/11/algorithm:62,
from main.cpp:1:
/usr/include/c++/11/bits/stl_algo.h: In instantiation of ‘_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = __gnu_cxx::__normal_iterator<const std::function<void()>*, std::vector<std::function<void()> > >; _Funct = void (*)(void (&&)())]’:
main.cpp:12:15: required from here
/usr/include/c++/11/bits/stl_algo.h:3820:12: error: invalid initialization of reference of type ‘void (&&)()’ from expression of type ‘const std::function’
3820 | __f(*__first);
| ~~~^~~~~~~~~~
如果没有 lambda 就无法做到这一点,因为
std::invoke
(像 中的许多其他函数一样std
)不允许获取其地址。您可以在此处查看有关它的更多信息:我可以获取标准库中定义的函数的地址吗?
如果有帮助的话,下面是使用 lambda 执行此操作的方法:
对于范围中的每个元素(在您的情况下是回调函数),将使用它作为参数调用 lambda。
然后您可以使用它
std::invoke
来调用回调函数元素:输出:
现场演示