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

如何在以std::pair为键的std::map中无冗余拷贝查找值?

无冗余拷贝查找std::map<std::pair<std::string, std::string>, some_type>的最优方案

要实现无字符串拷贝的查找,核心是利用C14引入的透明比较器结合C17的std::string_view,避免构造std::pair<std::string, std::string>时的字符串拷贝操作,具体步骤如下:

1. 调整map的比较器为透明类型

默认的std::map使用std::less<std::pair<std::string, std::string>>作为比较器,不支持跨类型的透明查找。我们需要显式指定比较器为std::less<>(即std::less<void>),它会自动推导比较操作的参数类型,无需严格匹配键类型:

#include <map>
#include <string>
#include <string_view>

std::map<std::pair<std::string, std::string>, some_type, std::less<>> my_map;

2. 使用std::pair<std::string_view, std::string_view>作为查找参数

std::string_view是轻量级的字符串视图,仅持有原字符串的指针和长度,不会拷贝内容。构造该pair传入find即可实现无拷贝查找:

const std::string str1 = "key_part1";
const std::string str2 = "key_part2";

// 无拷贝查找,string_view直接引用str1、str2的内容
auto it = my_map.find(std::pair<std::string_view, std::string_view>{str1, str2});

if (it != my_map.end()) {
    // 找到对应值,进行操作
    some_type& value = it->second;
}

为什么其他方法不行?

  • std::make_pair(str1, str2):会构造std::pair<std::string, std::string>,必然触发两次字符串拷贝。
  • std::make_pair(std::ref(str1), std::ref(str2)):std::ref返回的reference_wrapper会被隐式转换为std::string,依然会触发拷贝。
  • std::make_pair(std::move(str1), std::move(str2)):仅适用于可移动的字符串,且移动后原字符串会处于有效但未定义的状态,不符合题目中“str1、str2为常量或不可移动”的前提。

版本兼容性说明

  • 透明比较器std::less<>需要C++14及以上版本支持。
  • std::string_view和字符串与string_view的跨类型比较需要C++17及以上版本支持。

如果受限于旧C++标准,无法使用string_view,唯一的替代方案是预先缓存常用的std::pair<std::string, std::string>键对象,复用它们进行查找以减少拷贝次数,但这本质上是妥协方案,无法完全避免拷贝。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 13:42:38