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

能否将泛型模板lambda作为std::function存入std::unordered_map?

可行,两种实现方案结合你的场景说明

核心逻辑说明

泛型lambda本质是一个带有模板化operator()的匿名类,要存入std::unordered_map,要么针对每个目标类型实例化出固定签名的std::function,要么利用C++17及以上的特性直接使用带auto参数的std::function,以下是具体实现:


方案1:C++17及以上(简洁版,推荐)

直接使用支持auto参数的std::function,无需手动实例化lambda的模板参数:

#include <iostream>
#include <unordered_map>
#include <functional>
#include <tuple>
#include <sstream>
#include <string>
#include <type_traits>

int main() {
    // 泛型读取lambda:针对不同类型做编译期分支处理
    auto read_lambda = [](auto& val, const std::string& line) {
        std::istringstream iss(line);
        if constexpr (std::is_same_v<std::decay_t<decltype(val)>, std::string>) {
            std::getline(iss >> std::ws, val); // 字符串读取整行(跳过前置空白)
        } else if constexpr (std::is_integral_v<std::decay_t<decltype(val)>>) {
            iss >> val; // 整数直接读取
        }
        // 可扩展浮点数、自定义类型等分支
    };

    // 定义map:value为带auto参数的std::function,直接存入泛型lambda
    std::unordered_map<std::string, std::function<void(auto&, const std::string&)>> func_map;
    func_map["age"] = read_lambda;
    func_map["name"] = read_lambda;

    // 目标数据结构:std::tuple
    std::tuple<int, std::string> user_data;

    // 模拟扫描到的关键字和对应行数据
    func_map["age"](std::get<0>(user_data), "30");
    func_map["name"](std::get<1>(user_data), "Alice Smith");

    // 验证结果
    std::cout << "Age: " << std::get<0>(user_data) << "\n";
    std::cout << "Name: " << std::get<1>(user_data) << "\n";

    return 0;
}

方案2:兼容C++14(手动实例化lambda)

C++14不支持std::function的auto参数,需针对每个目标类型,将泛型lambda实例化为固定签名的std::function,可结合std::variant统一存储不同签名的函数:

#include <iostream>
#include <unordered_map>
#include <functional>
#include <tuple>
#include <sstream>
#include <string>
#include <type_traits>
#include <variant>

int main() {
    auto read_lambda = [](auto& val, const std::string& line) {
        std::istringstream iss(line);
        if (std::is_same<std::decay_t<decltype(val)>, std::string>::value) {
            std::getline(iss >> std::ws, static_cast<std::string&>(val));
        } else if (std::is_integral<std::decay_t<decltype(val)>>::value) {
            iss >> static_cast<int&>(val);
        }
    };

    // 用variant封装不同签名的std::function
    using ReadFunc = std::variant<
        std::function<void(int&, const std::string&)>,
        std::function<void(std::string&, const std::string&)>
    >;

    std::unordered_map<std::string, ReadFunc> func_map;
    // 手动实例化lambda为对应类型的function并存入
    func_map["age"] = static_cast<std::function<void(int&, const std::string&)>>(read_lambda);
    func_map["name"] = static_cast<std::function<void(std::string&, const std::string&)>>(read_lambda);

    std::tuple<int, std::string> user_data;

    // 用std::visit调用对应签名的函数
    std::visit([&](auto&& func) {
        if constexpr (std::is_invocable_v<decltype(func), int&, const std::string&>) {
            func(std::get<0>(user_data), "30");
        }
    }, func_map["age"]);

    std::visit([&](auto&& func) {
        if constexpr (std::is_invocable_v<decltype(func), std::string&, const std::string&>) {
            func(std::get<1>(user_data), "Alice Smith");
        }
    }, func_map["name"]);

    std::cout << "Age: " << std::get<0>(user_data) << "\n";
    std::cout << "Name: " << std::get<1>(user_data) << "\n";

    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 15:24:54