2016-04-24 7 views
3

だから、私の中にはstd::list<std::pair<int, std::string>>というクラスがあります。このクラスのイテレータを実装して、このリストに含まれる文字列を反復処理する方法はありますか?コンテナの項目のフィールドに対してイテレータを作成するにはどうすればよいですか?

たとえば、私のクラスでは、a,bおよびcのフィールドを持つstructのベクトルを持っています。逆参照を行うと(b, c)に対応するstd::pairを返すイテレータを作成できますか(おそらくベクトルのイテレータを継承していますかわかりません)。

反復子とは、std::vectorのイテレーターのようなものです:whatever.begin()経由で取得でき、前述のようにリスト内の文字列を反復することができます。

UPDわかりました、ここに私が欲しい情報があります。私のHashMapクラスでは、私はitemsを持っています:structsのリスト:それぞれがキー、値、それにテーブル内の場所へのポインタを持っています。私が必要とするのはイテレータです。私はitems.begin()を実行して取得できるものではありません。この反復子は、逆参照されると、私の構造体を返します。ユーザーがHashMap.begin()を呼び出したときに返すようなイテレーターが必要で、(key、value)に対応するstd::pairに逆参照する必要があります。

これは、うまくいけば、私の質問を明確にするはずです。以下のための変換イテレータを使用するには

#include <iostream> 
#include <list> 
#include <boost/range/adaptor/transformed.hpp> 
#include <boost/iterator/transform_iterator.hpp> 

int main() { 
    std::list<std::pair<int, std::string>> l; 
    auto extractor = [](auto&& elem) { return elem.second; }; 

    // Using a transformed range. 
    for(auto&& v: l | boost::adaptors::transformed(extractor)) 
     std::cout << v << '\n'; 

    // Using transform iterators. 
    for(auto i = boost::make_transform_iterator(l.begin(), extractor), j = boost::make_transform_iterator(l.end(), extractor); i != j; ++i) 
     std::cout << *i << '\n'; 
} 

template<class KeyType, class ValueType> 
struct node { 
    KeyType key; 
    ValueType value; 
    node** place; 

    node(KeyType key_ = KeyType(), ValueType value_ = ValueType()): key(key_), value(value_) {}; 
}; 
+0

任意のstruct defnitionsでは使用できません。これは、C++では利用できないランタイムリフレクションを必要とします。あなたはそれを使用する必要がある各具体的な構造体のために独自のイテレータ実装を提供することができます。そうするときには['std :: tie()'](http://en.cppreference.com/w/cpp/utility/tuple/tie)が便利です。 –

+0

リスト内の文字列を繰り返し処理しますか? – Galik

+0

あなたはそのようなイテレータが必要な理由について説明する必要があります。 – Holt

答えて

1

一つエレガントな方法が転換イテレータまたは形質転換された範囲を使用することです:

UPD2 ここでは私のstruct、それは場合に役立ちますですあなたはコンテナのような何かをすることができます:

struct MyContianer 
{ 
    std::list<std::pair<int, std::string>> container; 

    static auto constexpr first_extractor = [](auto&& elem) { return elem.second; }; 
    using iterator_first = decltype(boost::make_transform_iterator(container.begin(), first_extractor)); 
    iterator_first begin_first() { return {container.begin(), first_extractor}; } 
    iterator_first end_first() { return {container.end(), first_extractor}; } 

    static auto constexpr second_extractor = [](auto&& elem) { return elem.second; }; 
    using iterator_second = decltype(boost::make_transform_iterator(container.begin(), second_extractor)); 
    iterator_second begin_second() { return {container.begin(), second_extractor}; } 
    iterator_second end_second() { return {container.end(), second_extractor}; } 

}; 
decltype(MyContianer::first_extractor) constexpr MyContianer::first_extractor; 
decltype(MyContianer::second_extractor) constexpr MyContianer::second_extractor; 

int main() { 
    MyContianer c; 
    c.begin_first(); 
    c.begin_second(); 
} 
+0

まあ、私は、私は 'boost'などを使用することは許されていないと確信しています...これは素晴らしいですが、それは私を助けません – Akiiino

+0

@Akiiino Ifブーストを再利用することはできません。基本的なアイデアを再利用することができます。コンテナのイテレータクラステンプレートを作成します。テンプレートパラメータの1つは、変換関数/抽出オブジェクトタイプです。 –