如何创建包含不同返回类型函数的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
相关产品推荐
相关产品推荐

