2009-07-10 10 views
14

私はクラス任意のイテレータ(C++)から値の型を取得できますか?

template <typename Iterator, typename Value> 
class Foo { 
public: 
    Foo(const Iterator& it) { ... } 
    ... 
private: 
    map<Value, int> m_; 
    } 
}; 

を持っているが、テンプレートに値を取り除く方法はありますか?イテレータはSTLイテレータであってもそうでなくてもかまいませんが、その型がValueであることが保証されています。

私はSTLイテレータについてはiterator_traits<T>::value_typeを知っていますが、任意のイテレータタイプに対してValue型を自動的に取得する方法があるのだろうか?私が考えている

1つのトリック - と言うが、我々はヘルパークラスを持っている

template <typename Iterator, typename Value> 
class Bar { 
public: 
    Bar(const Iterator& dummy_iterator, const Value& dummmy_value) {} 
    ... 
}; 

その後、我々はバー(それ、*それ)としてバーをインスタンス化した場合、値の型がバーの内側に知られるであろう。しかし、私はBarとFooを組み合わせる良い方法を見つけることができません。

答えて

18

イテレータは、iterator_traits<Iterator>::value_typeを提供する必要があります。そうでなければ、イテレータではありません。 ISO C++ 2003 24.3.1 [lib.iterator.traits「イテレータ形質」:

のみ用語イテレータの にアルゴリズムを実装するためには、値との差に対応 タイプを決定しばしば に必要です具体的には イテレータタイプです。したがって、それは が必要であることIteratorそれぞれイテレータの 差分タイプ、値型と イテレータカテゴリとして定義されるイテレータの種類 、タイプ

iterator_traits<Iterator>::difference_type 
iterator_traits<Iterator>::value_type 
iterator_traits<Iterator>::iterator_category 

がある場合。

これ以外にも、任意のC++式のタイプを取得する一般的な方法はありません。 C++ 0xはdecltypeを入力して修正します。

+0

ありがとう、ISO C++標準への参照が役立ちます。 –

1

申し訳ありません。 Valueを取り除く正しい方法は、提案したとおりにiterator_traitsを使用することです。

STL以外のイテレータがネイキッドポインタの場合は、iterator_traitsのtypedefを無料で取得します。それ以外の場合は、STL以外のイテレータクラスで正しいtypedefを定義する必要があります。

詳細については、iterator traits documentationを参照してください。

1

イテレータの値の型を取得することについては、以前の回答は正しいです。

しかしもっとあります。あなたが考えているトリックはクラスではうまくいかないでしょう。 Barのような関数であった場合は、次の

template <typename Iterator, typename Value> 
void bar(const Iterator& dummy_iterator, const Value& dummmy_value) {} 

その後、型推論はbar(it, *it)のために働くだろうと、あなたはbarの内部で値の型を持っているでしょう。 (しかし、このトリックを使用するには、逆参照可能なイテレータを使用する必要があることに留意してください。イテレータは必ずしも適切ではありません。)

あなたはクラスのための型推論が存在しないように手動テンプレート引数IteratorValueを提供しなければならないBarクラスを使用してBar(it, *it)だろう何のコンパイルを使用していません。

+0

ありがとう!私は機能としてバーを使用することについて同じ考えをしましたが、多分私は何かが欠けていると思った。 –

関連する問題