2017-01-23 133 views
0
在一些仍然存在的代碼

一個映射元組使用C++商店參考那裏有地圖這種類型的:在另一個函數

std::map<int, std::tuple<int, std::vector<HlEdgeEntry*>*>> edgesMap; 

我現在想存儲的

std::tuple<int, std::vector<HlEdgeEntry*>*> 

以內的部分另一個優先隊列。 這樣,從優先級隊列提取時,我不需要運行地圖的.find方法。

這樣我PriorityQueue的定義如下:

typedef std::pair<int, std::tuple<int, std::vector<HlEdgeEntry*>*>> 
EdgePairType; 
typedef std::pair<int, EdgePairType> QueuePairType; 

struct CompareQueueEntry : 
public std::binary_function<QueuePairType, QueuePairType, bool> 
{ 
    bool operator() 
    (const QueuePairType firstQueuePair, 
     const QueuePairType secondQueuePair) const 
    { 
     return firstQueuePair.first < secondQueuePair.first; 
    } 
}; 

typedef std::priority_queue<QueuePairType, vector<QueuePairType>, 
CompareQueueEntry> PriorityQueueType; 

地圖本身還被使用在所有的代碼。

在另一個(initQueue())函數中插入優先級隊列比選擇下一個優先級(doWork())的位置要多。 這兩種方法都通過引用獲取priorityQueue和map,這兩個方法都在第三個函數controlWork()中定義,並調用前面提到的兩種方法。這看起來像如下:

std::map<int, std::tuple<int, std::vector<HlEdgeEntry*>*>> edgesMap; 
PriorityQueueType priorityQueue; 


k->initQueue(edgesOrelSource, edgesMap); 
k->doWork(edgesMap, priorityQueue); 

的問題是,從接收隊列中的元組後(內的doWork()),我想改變的元組值之一,使得它影響withing地圖中的條目。 更準確地說,我想將隊列鍵存儲到地圖tuple.first(int)中。出於某些功能原因,我無法提前完成此操作。 這則看起來像如下:

QueuePairType currPriorityPair = priorityQueue.top(); 
priorityQueue.pop(); 

int currPriority = currPriorityPair.first; 
EdgePairType currEdgePair = currPriorityPair.second; 

... = currEdgePair.first; 
std::tuple<int, std::vector<HlEdgeEntry*>*> currTuple = 
     currEdgePair.second; 

int newKey = recalculateKeyFromQueueForCurrentElement(); 
if(newKey > currPriority) 
{ 
    //reinsert currElement into Queue and go to next iteration 
    continue; 
} 

//set currPriority, cannot change any more in future 
std::get<int>(currTuple) = newKey; 

所以這段代碼剪斷的最後一行顯示了我想做的事情,使得地圖內的值發生了變化。

據我所知,這是不可能的,直到我使用指針作爲地圖內的映射值。但正如我所說,它仍然存在的代碼,我真的會避免改變。 但我的知識不是最好的,所以可能會有一些可能性。

如果沒有,也許這是一種更少的努力?

在此先感謝。

+0

爲什麼不只是有指針的優先級隊列? –

+0

你的代碼有點不清楚。 (什麼是'k'?什麼是'edgesOrelSource'?)我們可以跳過細節,並且可以說優先級隊列是否總是包含已經在地圖中的元素? –

+0

他們的其他對象這裏不感興趣我認爲 「優先級隊列是否總是包含已經在地圖中的元素」 - >是的 – Kaspatoo

回答

0

下面是一個非常普遍的方法,它有一箇中心std::map<K, T, Cmp>和一個輔助優先級隊列,用於管理地圖的一些元素。我們通過存儲指針來實現這一點,以便映射隊列中的元素,但是使用地圖的關鍵比較器(的副本)進行隊列排序。

我們可以這樣定義隊列:

using M = std::map<K, T, Cmp>; 

using Q = std::priority_queue< 
       M::mapped_type*, std::vector<M::mapped_type*>, QCmp<M>>; 

這裏我們使用:

template <typename M> 
class QCmp 
{ 
    using El = M::mapped_type*; 
    M::key_compare cmp_; 

public: 
    QCmp(M::key_compare cmp) : cmp_(cmp) {} 

    bool operator()(El lhs, El rhs) const 
    { 
     return cmp_(lhs->first, rhs->first); 
    } 
}; 

用法:

M m = /* ... */; 
Q q(m.key_comp()); 

q.push(&m[key]); // etc. 
+0

這意味着通過只添加一個&到地圖pair.second我得到一個指向它的指針,我可以將它存儲在隊列中。我在使用edgesMapIter迭代edgeMap時執行: priorityQueue.push(&((* edgesMapIter).second)); 對於I機會piorityQueues類型爲: typedef std :: pair *> *> EdgePairType; - >注意添加*最後> 在你的樣品之前,我不知道什麼 LHS->第一 做,因爲使用厄爾尼諾= M :: mapped_type *; 我明白mapped_type不一定有.second – Kaspatoo