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

如何存储带有不同比较器的std::map对象引用?

最优实现方案

由于std::map<int, int, std::greater<int>>和std::map<int, int, std::less<int>>是不同的具体类型,无法直接用单一类型的引用存储,推荐以下两种高效且符合你需求的实现方式:

方案一:使用std::variant(C++17及以上,推荐)

std::variant是类型安全的联合体,可以存储指定类型的引用(通过std::reference_wrapper包装),开销极低,能无缝对接现有使用std::greater/std::less的代码,完全适配你的场景。

示例代码:

#include <map>
#include <variant>
#include <functional> // 用于std::reference_wrapper

// 定义可存储两种map引用的variant类型
using MapRefVariant = std::variant<
    std::reference_wrapper<std::map<int, int, std::less<int>>>,
    std::reference_wrapper<std::map<int, int, std::greater<int>>>
>;

// 处理map的示例函数
void process_map(MapRefVariant map_ref) {
    // 通过std::visit分发处理两种类型的map
    std::visit([](auto&& wrapped_map) {
        auto& map = wrapped_map.get();
        // 这里直接操作map,比如遍历或修改
        for (const auto& [key, val] : map) {
            // 执行业务逻辑
        }
    }, map_ref);
}

int main() {
    std::map<int, int, std::less<int>> less_map = {{1,2}, {3,4}};
    std::map<int, int, std::greater<int>> greater_map = {{5,6}, {7,8}};

    MapRefVariant ref1 = std::ref(less_map);
    MapRefVariant ref2 = std::ref(greater_map);

    process_map(ref1);
    process_map(ref2);
    return 0;
}

方案二:抽象基类+模板包装器(兼容C++11及以上)

如果项目使用较旧的C++标准,可通过抽象基类定义统一操作接口,再用模板子类包装不同类型的map,通过基类指针/引用实现统一存储。这种方式兼容性更好,但需要提前定义好所需的操作接口。

示例代码:

#include <map>
#include <memory>

// 抽象基类,定义map的统一操作接口
class BaseMap {
public:
    virtual ~BaseMap() = default;
    // 示例接口:根据键获取值
    virtual int get_value(int key) const = 0;
    // 可根据需求添加插入、遍历等更多接口
};

// 模板子类,包装具体的map类型
template <typename Cmp>
class MapWrapper : public BaseMap {
public:
    MapWrapper(std::map<int, int, Cmp>& map) : map_ref_(map) {}
    int get_value(int key) const override {
        auto it = map_ref_.find(key);
        return it != map_ref_.end() ? it->second : -1; // 示例默认值
    }
private:
    std::map<int, int, Cmp>& map_ref_;
};

// 使用示例
int main() {
    std::map<int, int, std::less<int>> less_map = {{1,2}, {3,4}};
    std::map<int, int, std::greater<int>> greater_map = {{5,6}, {7,8}};

    std::unique_ptr<BaseMap> wrapper1 = std::make_unique<MapWrapper<std::less<int>>>(less_map);
    std::unique_ptr<BaseMap> wrapper2 = std::make_unique<MapWrapper<std::greater<int>>>(greater_map);

    // 通过基类指针调用统一接口
    wrapper1->get_value(1); // 返回2
    wrapper2->get_value(5); // 返回6
    return 0;
}

方案选择建议

  • 若使用C++17及以上,优先选方案一:std::variant类型安全、开销极小,无需额外定义接口,完全适配你与现有代码集成的需求,且不会引入自定义比较器的性能问题。
  • 若需兼容旧标准,再考虑方案二,但需提前明确所有需要的操作接口。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 02:40:27