重写对集合的访问权限以避免"double"查找

rewrite access to collection to avoid "double" finding

本文关键字:double 查找 权限 集合 访问 访问权 重写      更新时间:2023-10-16

我有这样的代码:

std::unordered_map<int64_t /*id_ord*/, LimitOrder> futOrders;
auto i = futOrders.find(orderId);
if (i == futOrders.end()) {
    LimitOrder& newOrder = futOrders[orderId];
            // work
} else {
    LimitOrder& futOrder = i->second;
            // another work
}

在这里,我执行两次"查找":第一次:auto i = futOrders.find(orderId);第二次:LimitOrder& newOrder = futOrders[orderId];

我能以某种方式重写它以避免"双重查找"吗?

您可以执行emplace,并检查返回值以了解项目是否已插入:

std::unordered_map<int64_t /*id_ord*/, LimitOrder> futOrders;
auto i = futOrders.emplace(
           std::piecewise_construct, std::tie(orderId), std::make_tuple());
if (i.second) {
    LimitOrder& newOrder = i.first->second;
            // work
} else {
    LimitOrder& futOrder = i.first->second;
            // another work
}

使用size()来实现是否插入了元素,如下所示:

auto old_size = futOrders.size();
LimitOrder& order = futOrders[orderId];
if (old_size < futOrders.size()) {
    LimitOrder& newOrder = order;
        // work
} else {
    LimitOrder& futOrder = order;
        // another work
}

假设有一种方法可以"确定订单是否为空",您可以这样做:

LimitOrder& anOrder = futOrders[orderId];
if (anOrder.empty())       
{
   // New order, do stuff that only new orders need. 
}
else
{
   // Old order, update it.
}

empty方法当然可以类似于if (anOrder.name == "")if (anOrder.orderId == 0)等。

您可以使用insert的这种过载:

std::pair<iterator,bool> insert( const value_type& value );

示例:

std::unordered_map<int, std::string> m { {0, "A"}, {1, "B"}, {2, "C"} };
int orderId = 1;
// attempt to insert with key you have and default constructed value type
auto p = m.insert( std::make_pair(orderId, std::string()) );
if (p.second) {
    // the element was inserted
} else {
    // the element was not inserted
    std::cout << p.first->second;  // will print "B"
}

在这两种情况下,p.first都是您搜索(或刚刚插入)的元素的迭代器。