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

如何在不复制数据的情况下获取std::map的键向量?

避免复制std::map键生成vector的方案

核心思路:避免复制的本质是存储原map中键的引用/指针,而非字符串副本。以下是几种可行方案,无需轻易修改原map的键类型:


方案1:返回存储键指针的vector

直接存储map中键的const指针,完全避免字符串复制,效率最高。

修改后的代码:

// MyClass.h
class MyClass {
private:
    std::map<std::string, MyType> my_map;
public:
    std::vector<const std::string*> getKeys() const;
};
// MyClass.cpp
#include <vector>
std::vector<const std::string*> MyClass::getKeys() const
{
    std::vector<const std::string*> keys;
    keys.reserve(my_map.size()); // 预分配空间,减少扩容开销
    for (const auto& entry : my_map) {
        keys.push_back(&entry.first);
    }
    return keys;
}

注意事项:调用者必须保证在使用这些指针时,MyClass对象(即内部的my_map)仍处于有效状态,否则会出现悬空指针问题。


方案2:返回存储引用包装器的vector

使用std::reference_wrapper包装键的const引用,用法更接近普通引用,避免指针的语法开销。

修改后的代码:

// MyClass.h
#include <functional> // 需包含此头文件
class MyClass {
private:
    std::map<std::string, MyType> my_map;
public:
    std::vector<std::reference_wrapper<const std::string>> getKeys() const;
};
// MyClass.cpp
#include <vector>
std::vector<std::reference_wrapper<const std::string>> MyClass::getKeys() const
{
    std::vector<std::reference_wrapper<const std::string>> keys;
    keys.reserve(my_map.size());
    for (const auto& entry : my_map) {
        keys.push_back(std::cref(entry.first)); // 生成const引用包装器
    }
    return keys;
}

使用方式:调用时通过get()方法获取引用:

for (const auto& key_ref : my_obj.getKeys()) {
    const std::string& key = key_ref.get();
    // 使用key
}

注意事项:同方案1,需保证MyClass对象的生命周期长于引用包装器的使用周期。


方案3:C++20+ 直接返回键视图(无需生成vector)

如果仅需遍历键而非存储,使用C++20的std::views::keys生成视图,完全零复制,无需创建vector。

修改后的代码:

// MyClass.h
#include <ranges> // 需包含此头文件
class MyClass {
private:
    std::map<std::string, MyType> my_map;
public:
    auto getKeys() const {
        return std::views::keys(my_map);
    }
};

使用方式:直接遍历视图:

for (const auto& key : my_obj.getKeys()) {
    // 使用key,无任何复制操作
}

关于改用std::shared_ptr<std::string>作为键的问题

不推荐轻易修改,原因如下:

  1. 默认情况下,std::map<std::shared_ptr<std::string>, MyType>会按指针地址排序,而非字符串内容,破坏原有的排序逻辑,需自定义比较器(如[](const auto& a, const auto& b) { return *a < *b; }),增加复杂度。
  2. 即使使用shared_ptr,生成vector时若存的是shared_ptr本身,仍会复制指针(虽然比复制字符串开销小,但不如直接存原键的指针/引用高效)。
  3. 仅当你需要键的生命周期完全独立于map时,才考虑此方案,否则上述方案更简洁高效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 11:25:29