1

このオブジェクトのメソッドに必要なwithobjectがあります。property

class Object {
   Property property;
}

次に、このオブジェクトをグループ化する必要があります。このグループには、一意のプロパティのみを持つオブジェクトが必要です。このオブジェクトを でグループ化するのは自然なことですsetoperator<or である場合は orを定義しunordered_set operator==ますhash()。大丈夫です。次に、別の問題が発生します。を使用してセット内のこのオブジェクトを見つける必要がありますpropertyObjectしたがって、このプロパティをそのフィールドに割り当てるタイプのオブジェクトを作成する必要があります。そして、これは私がここで気に入らないことです。

別のアプローチは、map. オブジェクトのプロパティへのポインタをコピーまたは作成し、それらをマップ内のキーとして使用します。それも二重の作品だと思います。

のようなものが欲しいのですがset、オブジェクト全体を使用するのではなく、オブジェクトのプロパティを使用して検索する機能があります。たとえば、次のように定義します。

class Object {
   Property property;
   bool operator<(Object obj) { return property < obj.property; }
   bool operator<(Property obj) { return property < obj.property; }
};
some::set<Object> objSet;

次に、次のことができます。

Object obj;
objSet.insert(obj);
objSet.find(obj.property);

私を助けるコンテナの実装を提供してもらえますか? boost、qt は許容されます。

4

3 に答える 3

5

Boost Multi-Index 配列は、必要なものかもしれません。この1 つのセットに対する複数の並べ替えの例は、探しているものとかなり一致しています。

typedef multi_index_container<
  Object,
  indexed_by<
    ordered_unique<member<Object,Property,&Object::property> >
  > 
> object_set;

object_set oset;
Property prop;
oset.find( prop );
于 2013-02-28T21:08:02.330 に答える
3

std::equal_rangeの 4 パラメータ オーバーロードを使用して、 aPropertyと anを比較するコンパレータを提供できObjectます。

struct Cmp
{
    bool operator() ( const Object& o, const Property& p ) const
    {
        return o.property < p;
    }
    bool operator() ( const Property& p, const Object& o ) const
    {
        return p < o.property;
    }
};

std::set<Object> s = ....;
Property property_val = ....;
auto r = std::equal_range(s.begin(),s.end(), property_val, Cmp());

もう 1 つのオプションはstd::find_if、適切な単項述語を使用することです。std::setしかし、 orの対数ルックアップは役に立ちませんstd::equal_range

于 2013-02-28T20:50:46.553 に答える
2

Boost Multi Indexを選ぶ

値が直接公開されていない場合は、必要に応じて Property からキー エクストラクタとインデックスを定義することもできます。(簡単に印刷できるように、Property を構造体に、Object を public にしましたが、Property::get_value() が public である限り、これは機能します)

#include <iostream>
#include <string>
#include <algorithm>

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/optional.hpp>

struct by_property_value{};
struct byseq{};
struct by_id{};

struct Property{
    int value;
    std::string name;

    int get_value() const{
        return value;
    }
};

class Object {
public:
   int id;
   Property property;
};

Object make_object(const int&id, const int& value, const std::string& name){
    Object res;
    res.id = id;
    Property p;
    p.value = value;
    p.name = name;
    res.property = p;
    return res;
}

bool operator<(const Object& lhs, const Object& rhs){
    return lhs.id < rhs.id;
}



using namespace boost;
using namespace boost::multi_index;

struct property_value_key_extractor{
    typedef int result_type;

    result_type operator()(const Object& o) const{
        return o.property.get_value();
    }
};

typedef multi_index_container<
    Object,
    indexed_by<
        sequenced<tag<byseq> >
        , ordered_unique<tag<by_id>,member<Object,int,&Object::id> >
        , ordered_non_unique<tag<by_property_value> , property_value_key_extractor >
    >
> Objects;


using namespace std;
int main(int argc, char *argv[]) {

    Objects objects;
    objects.push_back(make_object(1,1000,"a"));
    objects.push_back(make_object(2,200,"b"));
    objects.push_back(make_object(3,50,"c"));

    typedef Objects::index<by_property_value>::type objects_by_property_value;
    typedef objects_by_property_value::iterator property_value_iterator;

    property_value_iterator it = objects.get<by_property_value>().find(200);

    if(it != objects.get<by_property_value>().end()){
        cout << it->id << " " << it->property.get_value() << " " << it->property.name << endl;
    }

    cout << "Print by propety value" << endl;

    for(property_value_iterator it = objects.get<by_property_value>().begin(); it != objects.get<by_property_value>().end(); it++ ){
        cout << it->id << " " << it->property.get_value() << " " << it->property.name << endl;
    }

}

出力:

2 200 b
プロパティ値による印刷
3 50 c
2 200 b
1 1000 a

于 2013-02-28T21:33:47.023 に答える