嵌套std::map自定义比较器初始化问题求助
嵌套std::map自定义比较器初始化错误的修复
错误原因
- 外层map构造参数错误:
std::map<K,V,Comp>的构造函数仅接收自身的比较器实例,你传入的第二个参数CompareDateTime(dateTime)完全无效——内层容器的比较器无法通过外层map的构造传递。 - 内层map无法默认构造:
CompareDateTime类只有带参数的explicit构造函数,没有默认构造函数。当使用MyMap["alpha"]这类operator[]操作时,会尝试默认构造内层的std::map<std::string, int, CompareDateTime>,这会触发编译失败,因为内层map的比较器无法被默认初始化。 - 额外笔误:枚举名
ComparePoilicy存在拼写错误,修正为ComparePolicy更规范。
修复方案
- 修正外层map的初始化逻辑,仅传入自身的比较器实例;
- 在结构体A中存储内层比较器的策略参数,用于后续构造内层map;
- 避免使用
operator[]触发默认构造,改用emplace+std::piecewise_construct手动构造带指定比较器的内层map; - 移除比较器中不必要的模板
operator(),因为参数类型是确定的std::string,简化代码逻辑。
修复后的完整代码
#include <iostream> #include <map> #include <locale> #include <string> #include <boost/date_time/posix_time/posix_time.hpp> #include <boost/date_time/posix_time/posix_time_io.hpp> enum class ComparePolicy { custom1, custom2 }; struct CompareNames { explicit CompareNames(ComparePolicy policy) : policy(policy) {} bool operator()(const std::string& lhs, const std::string& rhs) const { if (policy == ComparePolicy::custom1) { return lhs < rhs; } else { return lhs > rhs; } } ComparePolicy policy; }; struct CompareDateTime { explicit CompareDateTime(ComparePolicy policy) : policy(policy) {} bool operator()(const std::string& lhs, const std::string& rhs) const { const boost::posix_time::ptime timelhs = boost::posix_time::time_from_string(lhs); const boost::posix_time::ptime timerhs = boost::posix_time::time_from_string(rhs); if (policy == ComparePolicy::custom1) { return timelhs < timerhs; } else { return timelhs > timerhs; } } ComparePolicy policy; }; struct A { explicit A(ComparePolicy dateTimePolicy, ComparePolicy namesPolicy) : dateTimePolicy(dateTimePolicy), MyMap(CompareNames(namesPolicy)) {} void fillMe() { // 封装内层map的插入逻辑,避免重复代码 auto insertInnerMap = [this](const std::string& name) { MyMap.emplace( std::piecewise_construct, std::forward_as_tuple(name), std::forward_as_tuple(CompareDateTime(dateTimePolicy)) ); }; insertInnerMap("alpha"); insertInnerMap("gamma"); insertInnerMap("beta"); // 通过find获取已构造的内层map,再插入数据 MyMap.find("alpha")->second["1981-08-20 08:05:00"] = 1; MyMap.find("alpha")->second["1981-08-20 10:05:00"] = 1; MyMap.find("alpha")->second["1981-08-20 09:05:00"] = 1; MyMap.find("gamma")->second["1981-08-20 08:05:00"] = 1; MyMap.find("gamma")->second["1981-08-20 10:05:00"] = 1; MyMap.find("gamma")->second["1981-08-20 09:05:00"] = 1; MyMap.find("beta")->second["1981-08-20 08:05:00"] = 1; MyMap.find("beta")->second["1981-08-20 10:05:00"] = 1; MyMap.find("beta")->second["1981-08-20 09:05:00"] = 1; } void printMe() { for (auto& item : MyMap) { std::cout << "Name: " << item.first << "\n"; for (auto& entry : item.second) { std::cout << " " << entry.first << " : " << entry.second << "\n"; } } } ComparePolicy dateTimePolicy; std::map<std::string, std::map<std::string, int, CompareDateTime>, CompareNames> MyMap; }; int main() { A test(ComparePolicy::custom1, ComparePolicy::custom2); test.fillMe(); test.printMe(); return 0; }
关键修改说明
- 外层map初始化修正:仅传递外层比较器
CompareNames(namesPolicy),符合std::map的构造规则; - 存储内层策略参数:新增
dateTimePolicy成员,确保构造内层map时能传递正确的比较器参数; - 手动构造内层map:使用
emplace和分段构造,避免operator[]触发的默认构造逻辑; - 简化比较器逻辑:移除不必要的模板
operator(),明确参数类型为std::string,提升代码可读性; - 修正拼写错误:将
ComparePoilicy改为ComparePolicy,符合英文拼写规范。
内容的提问来源于stack exchange,提问作者proton
相关产品推荐
相关产品推荐

