2

カスタム データ構造のベクトルを並べ替えるのに役立つ比較関数オブジェクトを作成したいと考えています。テンプレートを同時に使用しているため、正確に実装する必要がある場所と必要な追加コードを見つけるのに苦労しています。以下のコードのほとんどは無視できます。完全を期すために含まれていますが、比較関数オブジェクトは の最後で使用されますprintSummary()。一言で言えば、比較関数オブジェクトを実装するにはどうすればよいですか?

#include<map>
#include<vector>
//#include<iostream>
#include<algorithm>
using namespace std;

template <class T>
class Record{
   public:
   T item;
   int total;
};

   template<class T>
   bool compare(const Record<T> & a, const Record<T> & b){ //should a come before b?
      if(a.total > b.total)
         return true;
      if(a.total < b.total)
         return false;
      if(a.total == b.total){
         if(a.item < b.item)
            return true; 
         else
            return false;
      }
   }

template <class T>
class Counter{
   public:
      map<T, int> m;

   void printSummary(){

      typename map<T, int>::const_iterator itr; 
      vector< Record<T> > printlist;
      Record<T> temp;
      int i = 0;

      for( itr = m.begin(); itr != m.end(); ++itr ){
         temp.item = (*itr).first;
         temp.total = (*itr).second;
         printlist.push_back(temp);
         i++;
      }

      sort(printlist.begin(), printlist.end(), compare);

      //output sorted printlist contents
   }

};
4

2 に答える 2

0

これはこれまでのところ問題ないように見えますcompare。型で修飾する必要がありますT

sort(printlist.begin(), printlist.end(), compare<T>);

比較関数では、省略できます

if(a.total == b.total){

その時点では常に等しいからです。これをちょうどに減らすことができます

if (a.total > b.total)
    return true;

if (a.total < b.total)
    return false;

return a.item < b.item;
于 2013-04-13T13:40:15.510 に答える
0

への呼び出しで、インスタンス化せずsort()に関数テンプレート の名前を指定しています。

sort(printlist.begin(), printlist.end(), compare);
//                                       ^^^^^^^

関数テンプレートのそのままの名前は、コンパイラのオーバーロード セット全体を表します(セットには、そのテンプレートの可能なすべての特殊化が含まれます)。

明確にするために、 1 つの関数compare<>()のアドレスを提供するためにインスタンス化する必要があります。

sort(printlist.begin(), printlist.end(), compare<T>);
//                                              ^^^

または、 functorcompareを作成することもできます:

struct compare
{
   template<class T>
   bool operator () (const Record<T> & a, const Record<T> & b)
   {
      // should a come before b?
      if(a.total > b.total)
         return true;
      if(a.total < b.total)
         return false;
      if(a.total == b.total){
         if(a.item < b.item)
            return true; 
         else
            return false;
      }
   }
};

次に、テンプレートのインスタンス化なしで、この方法でそれを渡すことができsort()ます (ただし、以下に示すように、一時的なものでも問題ありませんが、ファンクターのインスタンスを作成する必要があります)。

sort(printlist.begin(), printlist.end(), compare());
//                                       ^^^^^^^^^
于 2013-04-13T13:37:54.307 に答える