2014-04-20 56 views
1

我有這樣的代碼:改寫訪問集合,以避免「雙重」發現

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];

我可以重寫它以某種方式避免「雙重發現」?

回答

2

您可以執行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 
} 
0

如何使用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 
} 
0

假設有辦法「確定的訂單是空的」,你可以這樣做:

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)

0

您可以使用01這個過載代替:

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是迭代的元素你搜索(或剛剛插入)。

+0

這有需要映射類型的建築甚至是缺點時,它已經在地圖上存在。 (一個不必要的和潛在的昂貴操作。) – Mankarse

+0

是的。我不知道用'emplace'也可以做到這一點。 +1給你的答案。 – jrok