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

C++嵌套std::map查找实现及.at、[]运算符使用咨询

你的实现存在3个会直接导致编译失败的问题,无法正常工作
  • 返回值类型不匹配:函数声明的返回值是float(基础数值类型),但你在不存在分支返回字符串字面量"NaN",二者类型完全不兼容,编译器会直接报错。如果要返回浮点标准定义的非数值,需要用std::numeric_limits<float>::quiet_NaN(),使用前要包含<limits>头文件;如果你需要返回字符串形式的"NaN",必须把函数返回值改成std::string。
  • 违反const语义:这个方法是const成员函数,意味着函数内部不能修改成员变量registration_by_date_time,但你最后返回值时用了map的下标运算符[]——map的[]没有const版本,它的设计逻辑是如果查询的键不存在,就自动插入一个默认构造的对应值,本质是修改操作,所以const上下文里根本不能调用[]。
  • 冗余拉低效率:你对外层键date做了至少3次重复的O(logn)查找(第一次find、两次at、最后一次[]),完全没必要,一次查找拿到迭代器就能复用结果。

你问的几个API使用问题解答

.at()方法用对了吗?

这部分逻辑没大问题:你先用find确认了date在外层map里存在,此时调用.at(date)肯定能拿到对应的内层map引用,不会触发.at()找不到键时抛std::out_of_range异常的逻辑。而且.at()是有const重载的,const上下文里调用是合法的,唯一的问题是重复调用做了多余查找。

能不能用下标运算符[]?

  • 在当前const修饰的成员函数里绝对不能用,原因前面说过,[]会潜在修改map,编译器直接拦截。
  • 就算你把函数的const限定去掉,也不推荐用:只要判断逻辑有一点疏漏,[]就会往map里插入你不需要的空内层map,平白污染原始数据。

能不能用second成员实现?

不仅可以,这还是最高效的写法。map::find()返回的迭代器指向的是std::pair<const 键类型, 值类型>结构,first存键,second存对应的值,拿到迭代器之后直接访问second不需要再做键查找,比反复调用at、[]少了多次对数时间复杂度的查询,性能最好。


修正后的可运行实现

先引入必要的头文件:

#include <map>
#include <string>
#include <limits>

符合你原有函数签名(返回float类型NaN)的实现:

float get_registration(const std::string & date, const std::string & time) const{
    // 外层日期只查一次
    auto date_it = registration_by_date_time.find(date);
    if (date_it == registration_by_date_time.cend()) {
        return std::numeric_limits<float>::quiet_NaN();
    }
    // 直接拿迭代器指向的内层map的const引用,不用重复查外层
    const auto& time_map = date_it->second;
    auto time_it = time_map.find(time);
    if (time_it == time_map.cend()) {
        return std::numeric_limits<float>::quiet_NaN();
    }
    // 取内层迭代器的值返回
    return time_it->second;
}

如果你确实需要返回字符串形式的"NaN",把函数返回值改成std::string,不存在的分支直接返回"NaN",存在的分支用std::to_string(time_it->second)把浮点值转成字符串返回即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 13:12:17