2017-01-23 135 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