1

STL およびブースト プライオリティ キューのインターフェイスには、

T const &   top () const;
void    pop ();

後者は最上位の要素を削除します。しかし、その要素を pop() した後もその要素を使い続けたい場合や、コピーを避けたい場合はどうすればよいでしょうか? たとえば、私が持っているとしpriority_queue<T> pqます。書きたい

const T& first = pq.top();      
pq.pop();
const T& second = pq.top();
analyze(second);
analyze(first);      // first *after* second

残念ながら、pop() するとすぐに最初の参照が無効になるため、segfault が発生します。

私は java の のようなソリューションを好みnextElement()ます。これは を返しtop()て実行しますpop()が、要素が範囲外になった場合にのみ要素を削除します。そうすれば、何をいつ行うかを追跡する必要がなくなりpop()ます。ただし、参照を aに取得しても use_count が増加しない priority_queue<shared_pointer<T> >ため、使用は役に立たないようです。shared_pointer

boost::fibonacci_heapそれが重要な場合、私はその効率的な使用を好みますpush()

アイデアや指針はありますか?ありがとう!

4

3 に答える 3

0

ではfibonacci_heap、順序付けられたイテレータを使用して、完了するまで要素をヒープに保持できます。

auto it = heap.ordered_begin();
const T& first = *it;  // picking up ref to first element
const T& second = *++it;  // and to second element
analyze(first, second);
heap.pop();  // and now drop them
heap.pop();
于 2013-03-30T03:24:12.283 に答える
0

を増やすコストを喜んで受け入れる場合は、私が両方をuse count伝えることができる限り、次のようにします。boost::shared_ptrstd::shared_ptr

#include <iostream>
#include <vector>
#include <memory>
#include <queue>
#include <boost/shared_ptr.hpp>

template< typename T >
struct deref_less
{
  //typedef std::shared_ptr<T> P;
  typedef boost::shared_ptr<T> P;
  bool operator()( const P& lhs, const P& rhs ) { return *lhs < *rhs; }
};

int main()
{
   //std::priority_queue< std::shared_ptr<int>, std::vector< std::shared_ptr<int> >, deref_less< int >  > pq ;
   std::priority_queue< boost::shared_ptr<int>, std::vector< boost::shared_ptr<int> >, deref_less< int >  > pq ;

    boost::shared_ptr<int>
      sp1( new int(10)),
      sp2( new int(11)),
      sp3( new int(3))
      ;

      pq.push(sp1) ;
      pq.push(sp2) ;
      pq.push(sp3) ;

      std::cout << *pq.top() << std::endl ;

      std::cout << sp2.use_count() <<std::endl ;

      //std::shared_ptr<int> sp4( pq.top() ) ;
      boost::shared_ptr<int> sp4( pq.top() ) ;

      std::cout << sp2.use_count() <<std::endl ;

      pq.pop() ;

      std::cout << sp2.use_count() <<std::endl ;
      std::cout << *sp4 << std::endl ;
}

オンラインstdはこちら

于 2013-03-30T03:02:27.910 に答える
0

std::move をサポートするコンパイラを使用できますか?

int main()
{       
    std::priority_queue<std::string> str_q;
    str_q.push("aaa");
    str_q.push("bbb");
    str_q.push("ccc");
    std::string strs[3];

    strs[0] = std::move(const_cast<std::string&>(str_q.top()));
    std::cout<<str_q.top()<<std::endl;
    str_q.pop();
    strs[1] = std::move(const_cast<std::string&>(str_q.top()));
    std::cout<<str_q.top()<<std::endl;
    str_q.pop();
    strs[2] = std::move(const_cast<std::string&>(str_q.top()));
    std::cout<<str_q.top()<<std::endl;
    str_q.pop();

    for(auto const &data : strs){
        std::cout<<data<<std::endl;
    }            

    return 0;
}

戻り値の型が std::string const& であるため、回答を編集します。少なくとも constness をキャストして移動することはできません。

于 2013-03-30T02:21:16.213 に答える