无get方法时提取std::multimap键私有成员到vector并去重
解决方案:无get方法提取私有成员并去重
核心思路
利用友元仿函数访问Object类的私有成员m_name,结合STL算法完成提取与去重:
- 给Object类声明友元仿函数,授权其访问私有成员
- 使用
std::transform提取所有m_name到vector - 借助multimap的有序特性,用
std::unique+erase高效去重
完整实现代码
#include <iostream> #include <map> #include <vector> #include <algorithm> #include <string> class Object { std::string m_name; /* no set or get function allowed */ public: Object(std::string name): m_name(name) {} friend bool operator< (const Object& o1, const Object& o2) { return o1.m_name.compare(o2.m_name) < 0; } // 声明友元仿函数,用于提取私有成员m_name friend struct NameExtractor; }; // 友元仿函数,可直接访问Object的私有成员 struct NameExtractor { const std::string& operator()(const std::pair<Object, int>& elem) const { return elem.first.m_name; } }; void testMap() { std::multimap<Object, int> m1; m1.insert(std::make_pair(Object("abc"), 1)); m1.insert(std::make_pair(Object("qwerty"), 2)); m1.insert(std::make_pair(Object("def"), 3)); m1.insert(std::make_pair(Object("qwerty"), 4)); std::vector<std::string> names; // 提取所有键对象的m_name到vector std::transform(m1.begin(), m1.end(), std::back_inserter(names), NameExtractor()); // 去重:multimap已按键排序,names天然有序,unique移除连续重复项后截断vector auto unique_end = std::unique(names.begin(), names.end()); names.erase(unique_end, names.end()); // 输出验证结果 for (const auto& name : names) { std::cout << name << '\n'; } } int main() { testMap(); return 0; }
关键细节说明
- 友元仿函数的作用:通过
friend声明,让NameExtractor获得Object类私有成员的访问权限,完美规避添加get/set方法的限制。 - STL算法的配合:
std::transform遍历multimap的每个键值对,通过仿函数将m_name批量存入vector。- 由于
std::multimap会自动按键排序(依赖已实现的operator<),提取后的namesvector是有序的,std::unique可以线性扫描移除连续重复元素,再用erase截断vector完成去重,时间复杂度为O(n)。
内容的提问来源于stack exchange,提问作者DrRzvn
相关产品推荐
相关产品推荐

