【问题标题】:Get a vector of map keys without copying?无需复制即可获取地图键向量?
【发布时间】:2022-11-27 06:08:10
【问题描述】:

我有一个对象映射,其中键是 std::string。如何在不复制数据的情况下生成键向量?

我是否需要更改我的地图以改为使用 std::shared_ptr<std::string> 作为键?或者你会推荐其他东西吗?

我当前的代码是这样的:

MyClass.h

class MyClass {
private:
    std::map <std::string, MyType> my_map;
public:
    const std::vector<std::string> MyClass::getKeys() const;
}

MyClass.cpp

const std::vector<std::string> MyClass::getKeys() const
{
    std::vector<std::string> keys = std::vector<std::string>();
    for (const auto& entry : my_map)
        keys.push_back(entry.first); // Data is copied here. How can I avoid it?
    return keys;
}

【问题讨论】:

  • 看起来像不必要的优化。
  • 您需要考虑生命周期和所有权。如果我调用getKeys() 然后从地图中删除一个元素,会发生什么?
  • C++20 有std::views::keys,为您提供范围键的只读视图,即std::views::keys(my_map) 将允许您在地图的键上迭代和执行其他范围操作,而无需复制元素。
  • 我会支持@Kevin 并问:你需要一个向量或者只是迭代键的能力?
  • 好点,我本身不需要vector。我将研究我不知道的视图事物。谢谢你。你对生命周期的看法是正确的。我可能在那里有问题。视图对此有帮助吗?

标签: c++ optimization copy clone shared-ptr


【解决方案1】:

正如凯文所建议的那样,std::views::keys 几乎就是为此而制作的。它产生的视图是一个轻量级对象,只不过是一个指向范围参数的指针,解决了所有权和生命周期问题。迭代此视图与迭代地图相同,唯一的区别是视图的迭代器取消引用基础地图值的第一个元素。

至于一些代码,它非常简单:

// ...
#include <ranges>

class MyClass {
private:
    std::map<std::string, MyType> my_map;
public:
    std::ranges::view auto getKeys() const;
};

std::ranges::view auto MyClass::getKeys() const
{
    return std::views::keys(my_map);
}

因为范围和概念是相辅相成的,所以我使用 std::ranges::view 来约束 auto 返回类型。这是一种有用的方法,可以让编译器和函数的用户知道它将返回特定类别的对象,而不必指定可能很复杂的类型。

【讨论】:

    猜你喜欢
    • 2021-05-03
    • 2012-09-26
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    • 2022-01-03
    相关资源
    最近更新 更多