2017-01-23 9 views
0

в некоторых до сих пор существующий код Theres карту этого типа: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()). Оба метода принимают приоритет Queue и карту по ссылке, так что оба определены в третьей функции controlWork(), вызывающей оба предыдущих упомянутых метода. Это выглядит следующим образом:

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


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

Проблема заключается в том, что после получения кортежа из очереди (в пределах DoWork()) Я хочу, чтобы изменить одно из значений кортежей таким образом, что это влияет на запись жгутов карты. Чтобы быть более точным, я хочу сохранить ключ очереди в карты 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'? Что такое' edgeOrelSource'?) Можем ли мы пропустить детали, и можете ли вы сказать, всегда ли очередь приоритетов содержит элементы, которые уже находятся на карте? –

+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

, что означает, просто добавив & к парам карт. указатель на него, который я могу хранить в очереди. В моем конкретном случае я выполняю while при итерации по краямMap с edgeMapIter: priorityQueue.push (& ((* edgeMapIter) .second)); Это для I случайного типа piorityQueues для: typedef std :: pair *> *> EdgePairType; -> отметить добавленный * до последнего> В вашей выборке Интересно, что lhs-> первый делает, так как с помощью El = M :: mapped_type *; Что я понимаю, что mapped_type не обязательно имеет .second – Kaspatoo

 Смежные вопросы

  • Нет связанных вопросов^_^