C++11中如何从含CustomClass的vector创建name字段的string集合?
解决方案:提取CustomClass的name字段创建std::setstd::string
你遇到的问题核心是:std::set的迭代器构造函数需要元素能隐式转换为集合的元素类型(这里是std::string),但CustomClass和std::string之间没有默认的转换规则,所以必须手动做字段映射。下面是几种C++11标准下的实现方式:
方法1:用std::transform + Lambda表达式(最推荐)
这是C++11里最简洁直观的写法,直接遍历vector的每个元素,提取name并插入到set中:
#include <vector> #include <set> #include <algorithm> // 必须包含这个头文件才能用std::transform #include <iterator> // 用于std::inserter struct CustomClass { std::string name; // 你的其他成员变量/函数... }; int main() { std::vector<CustomClass> vec; // 填充vec的数据,比如: // vec.push_back({"Alice"}); // vec.push_back({"Bob"}); // vec.push_back({"Alice"}); // set会自动去重 std::set<std::string> myset; // 用transform完成映射+插入 std::transform( vec.begin(), vec.end(), std::inserter(myset, myset.end()), // set没有push_back,用inserter适配 [](const CustomClass& obj) { return obj.name; } // Lambda提取name字段 ); }
关键细节:
std::inserter是因为std::set不支持push_back,它会返回一个迭代器适配器,自动调用myset.insert()来添加元素。- Lambda表达式在C++11里是新增特性,能快速定义一个临时的函数对象,用来提取
name字段。
方法2:先生成临时std::vectorstd::string再初始化set
如果你更习惯用set的迭代器构造函数,可以先把所有name提取到一个临时vector里,再用这个vector初始化set:
std::vector<std::string> name_list; name_list.reserve(vec.size()); // 预分配空间,避免多次扩容提升性能 std::transform( vec.begin(), vec.end(), std::back_inserter(name_list), [](const CustomClass& obj) { return obj.name; } ); std::set<std::string> myset(name_list.begin(), name_list.end());
这种方式和方法1逻辑一致,只是多了一个中间容器,适合需要保留name_list后续使用的场景。
方法3:用std::mem_fn替代Lambda
如果你不想写Lambda,C++11的std::mem_fn可以把类的成员变量转换成一个可调用对象,同样能完成字段提取:
#include <functional> // 必须包含这个头文件才能用std::mem_fn std::transform( vec.begin(), vec.end(), std::inserter(myset, myset.end()), std::mem_fn(&CustomClass::name) // 直接绑定name成员变量 );
std::mem_fn(&CustomClass::name)会返回一个函数对象,当它接收CustomClass对象时,会自动返回该对象的name字段,效果和Lambda完全一致。
内容的提问来源于stack exchange,提问作者ghostrider
相关产品推荐
相关产品推荐

