是否可从set或map中删除元素并获取原数值作为临时变量用于move()操作?
删除关联容器元素同时获取被删值的实现方案
针对C++标准库中的std::set、std::map及其无序版本容器,有成熟的实现方案可以满足你的需求:
C++17及以上版本(推荐方案)
C++17标准为所有标准关联容器新增了extract()成员方法,是最安全、无额外开销的实现方式:
- 调用
extract()时会将指定元素从容器中移除,同时返回一个节点句柄对象,该对象持有被移除元素的完整所有权 - 你可以直接从节点句柄中取出元素并调用
std::move()转移,全程不会产生元素拷贝开销
代码示例
std::set 场景
#include <set> #include <string> #include <utility> int main() { std::set<std::string> str_set = {"apple", "banana", "cherry"}; // 提取键为"banana"的元素,同时从容器中移除 auto node = str_set.extract("banana"); if (!node.empty()) { // 直接move被删除的元素,无拷贝 std::string target_val = std::move(node.value()); // 后续可正常使用target_val } }
std::map 场景
#include <map> #include <string> #include <utility> int main() { std::map<int, std::string> id_map = {{1, "张三"}, {2, "李四"}, {3, "王五"}}; auto node = id_map.extract(2); if (!node.empty()) { // map的节点句柄可以分别获取key和mapped value int deleted_key = std::move(node.key()); std::string deleted_val = std::move(node.mapped()); } }
C++11/14兼容方案
如果你使用的C版本低于C17,没有extract()可用,可以通过先查找、再转移、最后删除的逻辑实现,但要注意操作合法性:
由于
std::set的元素默认是const限定的,需要先做const_cast去掉const修饰后再move,只要保证自定义类型move后处于可析构的合法状态,该操作就是安全的。
#include <set> #include <string> #include <utility> int main() { std::set<std::string> str_set = {"apple", "banana", "cherry"}; auto it = str_set.find("banana"); if (it != str_set.end()) { // 先move元素,再删除 std::string target_val = std::move(*const_cast<std::string*>(&*it)); str_set.erase(it); } }
内容的提问来源于stack exchange,提问作者Bonita Montero
相关产品推荐
相关产品推荐

