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

如何创建包含不同返回类型函数的std::vector?解决初始化报错

问题分析与解决方案

你遇到的问题是编译器无法自动将函数指针推导转换为std::variant中对应的std::function类型,且原代码的FuncVariant还遗漏了char返回类型的std::function。以下是两种可行的解决办法:

方案1:显式构造std::function完成初始化

只需要在初始化每个pair时,显式构造对应的std::function,帮编译器明确要转换的目标类型,同时补上遗漏的char类型变体:

using FuncVariant = std::variant<
    std::function<std::string(const PlayerFRDb&)>,
    std::function<int(const PlayerFRDb&)>,
    std::function<char(const PlayerFRDb&)>,
    std::function<double(const PlayerFRDb&)>
>;

std::vector<std::pair<std::string, FuncVariant>> extractors = {
    {" TEAM ", std::function<std::string(const PlayerFRDb&)>(extractTeam)},
    {" NAME ", std::function<std::string(const PlayerFRDb&)>(extractName)},
    {" TYPE ", std::function<std::string(const PlayerFRDb&)>(extractProperty4)},
    {" WS ", std::function<int(const PlayerFRDb&)>(extractProperty0)},
    {" LS ", std::function<int(const PlayerFRDb&)>(extractProperty1)},
    {" W ", std::function<int(const PlayerFRDb&)>(extractProperty2)},
    {" L ", std::function<int(const PlayerFRDb&)>(extractProperty3)},
    {" WAY ", std::function<char(const PlayerFRDb&)>(extractProperty5)},
    {" LINE ", std::function<double(const PlayerFRDb&)>(extractProperty6)},
};

后续使用时,需用std::visit处理不同类型的std::function,示例如下:

const PlayerFRDb db;
for (const auto& [key, funcVar] : extractors) {
    std::visit([&](const auto& func) {
        std::cout << key << ": " << func(db) << "\n";
    }, funcVar);
}

方案2:自定义类型擦除类封装统一接口

如果你的场景需要统一调用这些提取器(比如批量输出结果),可以用类型擦除封装一个统一的调用接口,避免后续处理std::variant的繁琐:

class Extractor {
public:
    template<typename Func>
    Extractor(Func&& f) : m_impl(std::make_unique<Impl<Func>>(std::forward<Func>(f))) {}

    // 统一调用接口:传入PlayerFRDb,将结果输出到指定流
    void run(const PlayerFRDb& db, std::ostream& out) const {
        m_impl->invoke(db, out);
    }

private:
    struct ImplBase {
        virtual ~ImplBase() = default;
        virtual void invoke(const PlayerFRDb&, std::ostream&) const = 0;
    };

    template<typename Func>
    struct Impl : ImplBase {
        Func m_func;
        Impl(Func&& f) : m_func(std::forward<Func>(f)) {}

        void invoke(const PlayerFRDb& db, std::ostream& out) const override {
            out << m_func(db); // 依赖各类型的operator<<重载
        }
    };

    std::unique_ptr<ImplBase> m_impl;
};

// 构建统一的vector
std::vector<std::pair<std::string, Extractor>> extractors = {
    {" TEAM ", extractTeam},
    {" NAME ", extractName},
    {" TYPE ", extractProperty4},
    {" WS ", extractProperty0},
    {" LS ", extractProperty1},
    {" W ", extractProperty2},
    {" L ", extractProperty3},
    {" WAY ", extractProperty5},
    {" LINE ", extractProperty6},
};

// 使用示例
PlayerFRDb myDb;
for (const auto& [key, extractor] : extractors) {
    std::cout << key << ": ";
    extractor.run(myDb, std::cout);
    std::cout << "\n";
}

这种方式把不同返回类型的函数行为统一起来,调用时无需关心具体返回类型,更适合批量处理场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 18:23:10