You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不使用Lambda,用std::for_each和std::invoke调用容器内的std::function

问题:无需Lambda,单语句调用容器内的回调函数

我想完成一项练习:不使用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);
      |         ~~~^~~~~~~~~~
解决方案

问题核心是std::invoke的使用方式不对:它是模板函数,直接传递给std::for_each时编译器无法正确推导参数,且它期望的原生函数引用类型和容器内的std::function不匹配。以下是几种无需Lambda的可行方案:

方案1:用std::mem_fn提取std::function的调用操作符

std::mem_fn可以直接提取std::function的operator(),生成能调用该操作的可调用对象:

std::for_each(callbacks.cbegin(), callbacks.cend(), std::mem_fn(&std::function<void()>::operator()));

方案2:用std::bind绑定std::invoke参数

通过std::bind明确将迭代器元素作为参数传递给std::invoke:

std::for_each(callbacks.cbegin(), callbacks.cend(), std::bind(std::invoke<void>, std::placeholders::_1));

方案3:C++20以上用std::bind_front简化绑定

如果编译器支持C++20,std::bind_front可以更简洁地完成绑定:

std::for_each(callbacks.cbegin(), callbacks.cend(), std::bind_front(std::invoke<void>));

原写法失败原因

  • 直接传std::invoke时,编译器无法推导_Funct模板参数,因为std::invoke本身是模板而非具体函数对象;
  • 指定std::invoke<void(void)>后,它的签名要求接收原生函数引用,但容器内是const std::function<void()>,类型不匹配导致报错。

内容的提问来源于stack exchange,提问作者Oodini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 02:20:11