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

C++将lambda作为类参数存储时触发std::bad_function_call异常如何解决

问题原因

你的代码存在3处核心错误,共同导致了std::bad_function_call异常:

  1. Action构造函数实现缺失类作用域限定
    你在类外实现Action的有参构造函数时没有加Action::前缀,相当于只声明了有参构造但没有真正实现,编译器会生成默认构造函数初始化Action对象,不会对成员f做赋值,导致f是空的std::function。
  2. getAction方法返回类型不匹配
    类声明中getAction的返回值是Action类型,但实现时你写成了int,相当于把存储的Action对象强制转为int返回,再调用时拿到的是非法的Action实例,内部的f完全是无效值。
  3. operator()重载未实现
    你只声明了Action的()运算符重载,没有写具体实现,调用时会触发未定义行为。

修复方案

1. 修正Action构造函数与运算符重载实现

给构造函数加上类作用域限定,同时补充()运算符的实现,推荐用初始化列表初始化成员提升效率:

typedef std::function<int(int)> func;

struct Action {
    Action(func);
    int operator()(int x);
    func f;
};

// 加类作用域限定,用初始化列表赋值
Action::Action(func f) : f(std::move(f)) {}

// 实现运算符重载
int Action::operator()(int x) {
    return f(x);
}

2. 修正Learning类的getAction实现

把返回值类型改回Action,可选择增加边界检查避免数组越界:

class Learning
{
public:
    void addAction(Action);
    Action getAction(int idx);
private:
    std::vector<Action> actions;
};

void Learning::addAction(Action act)
{
    actions.push_back(act);
}

// 修正返回值类型为Action
Action Learning::getAction(int idx)
{
    if (idx < 0 || idx >= actions.size()) {
        throw std::out_of_range("索引超出actions范围");
    }
    return actions[idx];
}

3. 可选逻辑优化

你当前lambda用的是后置自增y++,返回的是自增前的原值,运行后会输出0,如果需要返回自增后的值可以改成前置自增++y。


修复后完整运行代码

#include <iostream>
#include <functional>
#include <vector>
#include <stdexcept>

typedef std::function<int(int)> func;

struct Action {
    Action(func);
    int operator()(int x);
    func f;
};

Action::Action(func f) : f(std::move(f)) {}

int Action::operator()(int x) {
    return f(x);
}

class Learning
{
public:
    void addAction(Action);
    Action getAction(int idx);
private:
    std::vector<Action> actions;
};

void Learning::addAction(Action act)
{
    actions.push_back(act);
}

Action Learning::getAction(int idx)
{
    if (idx < 0 || idx >= actions.size()) {
        throw std::out_of_range("索引超出范围");
    }
    return actions[idx];
}

int main(){
    Learning robot;
    robot.addAction(Action([](int y) ->int{return ++y; }));
    std::cout << robot.getAction(0)(0) << std::endl; // 输出1
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 06:36:04