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

在std::unordered_set中为自定义Position类型正确使用emplace函数的问题

在std::unordered_set中为自定义Position类型正确使用emplace函数的问题

嘿,我看你已经在为自定义Position类型适配std::unordered_set做准备了——写了operator==用于相等判断,还定义了Position_hash哈希器,这两步走对了就成功一半啦!不过你贴的代码里main函数的unordered_set定义没写完,我来帮你补全,再仔细讲讲怎么正确用emplace。

首先,先把代码补全到可运行的状态,顺便优化下细节:

#include <unordered_set>
#include <iostream> // 用来验证插入结果

struct Position {
    int y;
    int x;
    
    // 建议显式加带参数的构造函数,让emplace的使用更直观高效
    Position(int y_, int x_) : y(y_), x(x_) {}
    
    bool operator==(const Position& other) const
    {
        return this->x == other.x && this->y == other.y;
    }
};

struct Position_hash {
    inline std::size_t operator()(const Position& v) const
    {
        // 你原来的简单哈希方式,小范围坐标完全够用
        return v.y * 31 + v.x;
        
        // 如果坐标范围很大,怕哈希冲突的话,可以换这种组合哈希方式
        // std::size_t h1 = std::hash<int>()(v.x);
        // std::size_t h2 = std::hash<int>()(v.y);
        // return h1 ^ (h2 << 1);
    }
};

int main() {
    // 必须指定哈希器类型为Position_hash,不然unordered_set不知道怎么算哈希
    std::unordered_set<Position, Position_hash> positions_set;
    
    // 重点:emplace的正确高效用法——直接传Position构造函数的参数,原地构造对象
    // 这种方式比先构造临时Position再insert更省性能,少一次拷贝/移动
    positions_set.emplace(1, 2); // 原地构造y=1、x=2的Position
    positions_set.emplace(3, 4);
    
    // 当然也可以传已构造的Position对象,但这样就没发挥emplace的优势了
    positions_set.emplace(Position{5, 6});
    
    // 验证插入是否成功
    if (positions_set.count(Position{1, 2})) {
        std::cout << "坐标(1,2)已经在集合里啦\n";
    }
}

这里再划几个关键细节:

  • 显式构造函数很实用:虽然编译器会给结构体生成默认构造,但加个Position(int y_, int x_)的构造函数,能让你直接用emplace(1,2)这种简洁写法,完美发挥emplace原地构造的高效性。
  • 哈希与相等判断要匹配:unordered_set先靠哈希器分组,再用operator==确认元素是否真的相等,所以这两个函数的逻辑要一致——你现在的实现都是基于x和y,完全没问题。
  • 哈希冲突的小优化:如果你的坐标范围很大,原来的简单哈希可能会有较多碰撞,换成标准库哈希组合的方式,能降低冲突概率,让集合的查找插入更高效。

要是你不想加显式构造函数,那emplace就只能传Position临时对象,比如positions_set.emplace(Position{1,2}),但这样和直接用insert差别不大,浪费了emplace的优势。

备注:内容来源于stack exchange,提问作者Awed2

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 16:14:50