3

私はboost::multi_indexコンテナで作業しています。基本的に、データ セット情報が完全である場合は、いくつかのデータと情報で構成されます (アイテムがコンテナーに追加された時点では、情報はまだ完成していません)。注文品がコンテナに追加されたことを知る必要があるため、コンテナは順序付けされています。

#include <boost/multi_index_container.hpp>    
#include <boost/multi_index/hashed_index.hpp>    
#include <boost/multi_index/ordered_index.hpp>    
#include <boost/multi_index/member.hpp>    
#include <boost/multi_index/composite_key.hpp>    
#include <boost/multi_index/sequenced_index.hpp>    
#include <boost/multi_index/key_extractors.hpp>    


struct indexed_struct    
{    
    unsigned int identifier;    
    unsigned int iterationFinished;    

    indexed_struct():    
        identifier(0), iterationFinished(0){}

    indexed_struct(unsigned int identifier, unsigned int iterationFinished):    
        identifier(identifier), iterationFinished(iterationFinished){}



    friend std::ostream& operator<<(std::ostream& os,const indexed_struct& c)    
    {    
        os<<c.identifier<<std::endl;    
        return os;    
    }
};

struct identifierTag {};    
struct finishedTag {};


typedef boost::multi_index::multi_index_container<    
    indexed_struct,    
        boost::multi_index::indexed_by<boost::multi_index::sequenced<>,    
            boost::multi_index::ordered_unique<boost::multi_index::tag<identifierTag>,    
            BOOST_MULTI_INDEX_MEMBER(indexed_struct, unsigned int, identifier)    
        >,    
        boost::multi_index::ordered_non_unique<boost::multi_index::tag<finishedTag>,    
            BOOST_MULTI_INDEX_MEMBER(indexed_struct, unsigned int, iterationFinished)    
        >    
    >    
> cmm_iteration_table;



void setFinished(cmm_iteration_table& table, unsigned int iteration)    
{    
    cmm_iteration_table::index<identifierTag>::type::iterator it;    
    it = table.get<identifierTag>().find(iteration);    
    indexed_struct mod(*it);    
    mod.iterationFinished = 1;    
    table.get<identifierTag>().replace(it, mod);

}


void main()    
{    
    cmm_iteration_table table;

    //add some items with iterationFinished set to 0    
    table.push_back(indexed_struct(30,0));    
    table.push_back(indexed_struct(20,0));    
    table.push_back(indexed_struct(40,0)); 

    //now set iterationFinished to 1 in a random order
    setFinished(table, 30);    
    setFinished(table, 40);    
    setFinished(table, 20);

    //try to get iterator for iterationFinished == 1 and sequenced
    //30-20-40 as added

    std::copy(table.get<finishedTag>().equal_range(1).first, table.get<finishedTag>().equal_range(1).second, std::ostream_iterator<indexed_struct>(std::cout)); //outputs 20,40,30 but 30, 20, 40 is intended

    std::copy(table.begin(), table.end(), std::ostream_iterator<indexed_struct>(std::cout)); //outputs 30,20,40, but would also output items where iterationFinished == 0

}

iterationFinished が 1 に設定されているシーケンス項目を反復処理する反復子ペアを取得したいと考えています。

最初の std::copy には iterationFinished フラグへのインデックスが付いていますが、順序が正しくありません (コンテナにプッシュされたアイテムとして順序を指定したかったという意味で)

2 番目の std::copy は正しい順序を示しますが、 iterationFinished == 0 のアイテムも出力します。

ヒントはありますか?

4

1 に答える 1

1

使ってみてboost::filter_iterator

このようなもの:

struct is_finished 
{
    bool operator()(indexed_struct const& x) { return x.iterationFinished; }
};

typedef cmm_iteration_table::index<identifierTag>::type::iterator iterator_type;

iterator_type it, ite;    
it = table.get<identifierTag>().begin();
ite = table.get<identifierTag>().end();

typedef boost::filter_iterator<is_finished, iterator_type> filter_iter_t;
filter_iter_t f_it(is_finished(), it, ite), f_ite(is_finished(), ite, ite);

std::copy(f_it, f_ite, std::ostream_iterator<indexed_struct>(std::cout));
于 2012-09-13T19:24:05.740 に答える