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

使用Boost.DI时动态绑定接口数组的Lambda表达式未执行问题

boost::di动态创建Log实现数组时Lambda未执行问题分析与解决

在使用boost::di进行依赖注入时,用于根据运行时条件动态创建Log接口实现类(ConsoleLog、FileLog)数组的Lambda表达式未执行,注入器配置完成后Lambda完全未被调用。

相关代码

#include <boost/di.hpp>
#include <iostream>
#include <memory>
#include <vector>

namespace di = boost::di;

struct Log {
    virtual ~Log() = default;
    virtual void log(const std::string& message) = 0;
};

struct ConsoleLog : Log {
    void log(const std::string& message) override {
        std::cout << "ConsoleLog: " << message << std::endl;
    }
};

struct FileLog : Log {
    void log(const std::string& message) override {
        std::cout << "FileLog: " << message << std::endl;
    }
};

class A {
public:
    A(std::vector<std::shared_ptr<Log>>& logs) : logs_(logs) {
        std::cout << logs_.size() << std::endl;
        for (auto& p : logs_) {
            p->log("test A");
        }
    }

private:
    std::vector<std::shared_ptr<Log>>& logs_;
};

int main() {
    bool needConsole = true;
    bool needFile = false;

    auto injector = di::make_injector(
        di::bind<Log*[]>().to([&](const auto& injector) -> std::vector<std::shared_ptr<Log>> {
            std::vector<std::shared_ptr<Log>> logs;
            std::cout << "Lambda executing" << std::endl;
            if (needConsole) {
                logs.push_back(injector.template create<std::shared_ptr<ConsoleLog>>());
            }
            if (needFile) {
                logs.push_back(injector.template create<std::shared_ptr<FileLog>>());
            }
            return logs;
        }).in(di::singleton)
    );

    auto a = injector.create<A>();
    return 0;
}

已排查步骤

  • 直接调用Lambda测试:手动调用该Lambda创建std::vector<std::shared_ptr<Log>>,确认Lambda逻辑本身无问题;
  • 简化Lambda逻辑:移除条件判断,仅创建单个ConsoleLog实例,Lambda仍未触发;
  • 添加日志输出:在Lambda内部及调用前后添加日志,确认Lambda未执行。

问题原因分析

核心问题是绑定类型与依赖类型不匹配:

  1. 代码中绑定的类型是Log*[](C风格数组类型),但类A的构造函数依赖的是std::vector<std::shared_ptr<Log>>,boost::di无法将数组类型的绑定匹配到vector类型的依赖,因此不会触发对应的Lambda;
  2. Lambda的返回值是std::vector<std::shared_ptr<Log>>,与绑定的数组类型完全不兼容,导致绑定规则无效。

此外,构造函数中使用std::vector<std::shared_ptr<Log>>&非const引用,boost::di默认会创建临时对象,可能引发引用失效的问题,也是潜在隐患。

解决建议

1. 修正绑定类型

将绑定的类型改为与依赖一致的std::vector<std::shared_ptr<Log>>,让boost::di能正确匹配依赖并触发Lambda。

2. 调整构造函数参数

将构造函数的参数改为const std::vector<std::shared_ptr<Log>>&或直接传值,避免临时对象引用失效的问题。

3. 优化Lambda实现

如果目标类无额外依赖,直接用std::make_shared创建实例更简洁;若需要通过injector管理依赖,可保留injector参数传入Lambda。

修正后代码示例

#include <boost/di.hpp>
#include <iostream>
#include <memory>
#include <vector>

namespace di = boost::di;

struct Log {
    virtual ~Log() = default;
    virtual void log(const std::string& message) = 0;
};

struct ConsoleLog : Log {
    void log(const std::string& message) override {
        std::cout << "ConsoleLog: " << message << std::endl;
    }
};

struct FileLog : Log {
    void log(const std::string& message) override {
        std::cout << "FileLog: " << message << std::endl;
    }
};

class A {
public:
    // 改为const引用,避免临时对象引用失效
    A(const std::vector<std::shared_ptr<Log>>& logs) : logs_(logs) {
        std::cout << logs_.size() << std::endl;
        for (const auto& p : logs_) {
            p->log("test A");
        }
    }

private:
    const std::vector<std::shared_ptr<Log>>& logs_;
};

int main() {
    bool needConsole = true;
    bool needFile = false;

    auto injector = di::make_injector(
        // 绑定正确的vector类型
        di::bind<std::vector<std::shared_ptr<Log>>>().to([&]() {
            std::vector<std::shared_ptr<Log>> logs;
            std::cout << "Lambda executing" << std::endl;
            if (needConsole) {
                logs.push_back(std::make_shared<ConsoleLog>());
                // 若需通过injector创建,可保留以下代码
                // logs.push_back(injector.create<std::shared_ptr<ConsoleLog>>());
            }
            if (needFile) {
                logs.push_back(std::make_shared<FileLog>());
            }
            return logs;
        }).in(di::singleton)
    );

    auto a = injector.create<A>();
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 22:55:09