2016-12-09 8 views
4

メンバーとしてstd::listを含むC++クラスがあります。次に、別のコンテナの値をそのリストに挿入するために使用できるメソッドを追加します。関数パラメータにC++で使用される "汎用"イテレータ型はありますか?

template<class factType> 
class BeliefSet 
{ 
    std::list<factType> m_List; 
    void SetFacts(??? IterBegin, ??? IterEnd) 
    { 
     m_List.insert(m_List.end(), IterBegin, IterEnd); 
    } 
}; 

今私の質問は次のとおりです:私はそれがいずれかのイテレータ(または少なくとも最も一般的)を取ることができるように、との???を置き換えるために何をしなければならないのlistようstdコンテナ、vectorなど、このような何か?私はstd::iterator<std::input_iterator_tag, factType>で試しましたが、それはうまくいかないようです。これはまた、このように、コピーコンストラクタで動作する必要があることを

注:

const std::list<factType>& GetFacts() const 
{ 
    return m_List; 
} 

// Copy constructor. 
explicit BeliefSet(const BeliefSet& Other) 
{ 
    auto facts = Other.GetFacts(); 
    SetFacts(facts.begin(), facts.end()); 
} 
+2

テンプレートは、任意の入力を受け入れるようにするため、 'm_list.insert'はより複雑なテンプレートの控除をiteratorとして検証しますか? – ShadowRanger

+0

[std :: iterator](http://en.cppreference.com/w/cpp/iterator/iterator)があります。それで、あなた自身のイテレータクラスを作成できましたか? –

+0

なぜテンプレートを使用せず、パラメータに「InputIterator」という名前を付けますか? – NathanOliver

答えて

5

SetFactsをテンプレートにする必要があります。通常、メソッドがインラインでなければならないため、これは不利になります。しかし、すでにBeliefSetがクラステンプレートであるため、問題はありません。

template<class factType> 
class BeliefSet 
{ 
    std::list<factType> m_List; 

    template <class It> 
    void SetFacts(It IterBegin, It IterEnd) 
    { 
     m_List.insert(m_List.end(), IterBegin, IterEnd); 
    } 
}; 

あなたはイテレータではない何かをSetFactsを呼び出す場合は、list::insertのうち、エラーメッセージを取得します。あなたが本当に幸運なら、あなたはそれらを理解することができるかもしれません!

私は反復子を(const参照ではなく)値で渡すことに注意してください。これは、反復子が通常は反復子をコピーするのが安価であると予想しているからです。

2

使用iterator_tag

template<class factType> 
class BeliefSet 
{ 

    std::list<factType> m_List; 
    template <typename Iter> 
    void SetFacts(Iter IterBegin, Iter IterEnd) 
    { 
     SetFacts_Impl(IterBegin, IterEnd, 
     typename std::iterator_traits<Iter>::iterator_category()); 
    } 
private: 
    template <typename Iter> 
    void SetFacts_Impl(Iter IterBegin, Iter IterEnd, std:: bidirectional_iterator_tag) 
    { 
     std::copy(IterBegin, IterEnd, std::back_inserter(m_List)); 
    } 
}; 

これは少なくともbidirectional iteratorによって設定された要件に従うことを任意のイテレータを取ることを確認します。だから、両方listvector

+0

'list'と' vector'は構築のために入力イテレータしか必要としません。 – NathanOliver

+0

'SetFacts'で直接' m_List.insert'を呼び出すと何が得られますか? –

+0

@MartinBonner何もありません。私はちょうどこの方法でそれを好んだ。 – Arunmu

2
template <class Iter> 
void SetFacts(Iter first, Iter last) 
    { 
     m_List.insert(m_List.end(), first, last); 
    } 

をカバーする私はまた、通常のイディオムに引数の名前を変更しました。

関連する問題