、ここで、C++ 11とC++ 14には、そのような事をすることが多く容易になります。 iteratorは、その核心で、逆参照可能であり、増分可能なものである。それがinput iteratorであれば、それにも匹敵します。あなたが望むように見えるので、後者と一緒に行きましょう。
最も単純なバージョンはvoid_t
を使用することであろう。
template <typename... >
using void_t = void;
ベースケース:
template <typename T, typename = void>
struct is_input_iterator : std::false_type { };
有効なケースの特殊:
template <typename T>
struct is_input_iterator<T,
void_t<decltype(++std::declval<T&>()), // incrementable,
decltype(*std::declval<T&>()), // dereferencable,
decltype(std::declval<T&>() == std::declval<T&>())>> // comparable
: std::true_type { };
別名:
template <typename T>
using is_input_iterator_t = typename is_input_iterator<T>::type;
iterator_category
に頼るか、過負荷解決を使用して面倒なC++ 03スタイルのチェックを使用する必要はありません。表現SFINAEはここにあります。
氏Wakelyコメントで指摘したように、[iterator.traits]ことを必要とする:タイプ
、
Iterator
場合は イテレータのタイプであることが要求される
iterator_traits<Iterator>::difference_type
iterator_traits<Iterator>::value_type
iterator_traits<Iterator>::iterator_category
は、反復子の差異タイプ、値タイプ、および反復子カテゴリとしてそれぞれ定義されます。
だから我々は単にそれをチェックするために、当社のイテレータ形質を定義することができます。
template <class T, class = void>
struct is_iterator : std::false_type { };
template <class T>
struct is_iterator<T, void_t<
typename std::iterator_traits<T>::iterator_category
>> : std::true_type { };
iterator_traits<T>::iterator_category
が悪い形成されている場合は、T
がイテレータではありません。
私はコンセプトチェックはあなたを助けることができます。しかし、それは簡単ではない。 –
あなたは本当に知りたい**が必要ですか?あなたが見つけたときに何をするつもりですか?型が演算子*と演算子++を実装していることをテストするだけで十分でしょうか? –
@Karl Knechtel:私の目的は、型Tに演算子*と演算子++(組み込み演算子を含む)がある場合、is_iterator :: valueはゼロではありません。 –
xmllmx