3

Name() などの属性アクセス メンバー関数を使用して要素を並べ替えることができるコンテナーを開発したいと考えています。以下のように使いたい

SortedVector<T, &T::Name> v;
T t;
v.Add(t);
v.FindElementWithName("AName");

テンプレートクラスを宣言する方法は? どうもありがとう。

4

2 に答える 2

2

関数の結果の型を 1 つだけ許可しない限り、思い描く単純な使用法を許可する宣言はありません。

その制限により、たとえば次のことができます

template< class Item, std::string (Item::*)() const >
class SortedVector;

しかし、より一般的に(単純な表記法をサポートしていない)、できること

template< class Item, class Result, Result (Item::*)() const >
class SortedVector;

とにかく、主な問題は、標準ライブラリのクラスをどのように活用するかです。

std::vectorを保管std::map用に、 を仕分け用に使用すると思います。

于 2012-12-30T06:03:02.077 に答える
1

2 つのオブジェクトの比較ではなく、1 つのオブジェクトからの「キーゲッター」に基づいて並べ替えを提供します。ラムダを使用する C++11x バージョンは、かなりクリーンになるはずです (これは、古い gcc 4.4 コードから変更されています)。

#include <algorithm>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>
#include <string>
#include <vector>

template <
  typename T,
  typename K
> struct sort_by_key_comparator {

  sort_by_key_comparator(boost::function<K(const T&)> keygetter)
    :_keygetter(keygetter){}

  bool operator()(const T& a,const T& b) {
    return (_keygetter(a)<_keygetter(b));
  }

  boost::function<K(T)> _keygetter;
};

// Sort an iterator range based on comparison of
// keys of type K retrieved from ojects of type T
template <
  typename IT,
  typename T,
  typename K
> void sort_by_key(
  IT first,
  IT last,
  boost::function<K(const T&)> keygetter
) {
  sort_by_key_comparator<T,K> cmp(keygetter);
  std::sort(first,last,cmp);
}

class data {

public:

  data(int id,const std::string& txt)
    :_id(id),_txt(txt){}

  int get_id() const {return _id;}

  const std::string& get_txt() const {return _txt;}

private:
  int _id;
  std::string _txt;
};

int main(int,char**) {

  std::vector<data> v;
  v.push_back(data(0,"d"));
  v.push_back(data(3,"c"));
  v.push_back(data(1,"b"));
  v.push_back(data(2,"a"));

  boost::function<int(const data&)> idkey=
    boost::bind(&data::get_id,_1);

  sort_by_key(v.begin(),v.end(),idkey);

  for (size_t i=0;i<v.size();++i) 
    std::cout << v[i].get_id() << ", " << v[i].get_txt() << std::endl;

  std::cout << std::endl;

  boost::function<std::string(const data&)> txtkey=
    boost::bind(&data::get_txt,_1);

  sort_by_key(v.begin(),v.end(),txtkey);

  for (size_t i=0;i<v.size();++i)
    std::cout << v[i].get_id() << ", " << v[i].get_txt() << std::endl;
}

興味深いことに、Python のソートはこの「keygetter」スタイルを使用しますが、C++ の STL/std ライブラリはもちろん2 オブジェクト コンパレータに基づいています。Scalaは両方のスタイルを ( と を介しsortBysortWith) 便利に提供します。

于 2012-12-30T13:10:27.793 に答える