2017-11-27 7 views
4

をにiterator_traitsのstdは::考えるのlibstdC++の乖離とのlibC++

error: no member named ' iterator_category ' in ' std::__1::iterator_traits<Iter> ' std::is_same<std::iterator_traits<Iter>::iterator_category, Iter::iterator_category>::value, "");

Iter::iterator_categoryが標準入力カテゴリの1つである場合、静的アサーションは成功します。例えば、 std::input_iterator_tag

私見

それが失敗してはならない、なぜなら[iterator.traits]#2でC++のドラフト状態:

If Iterator has valid ([temp.deduct]) member types difference_­type , value_­type , pointer , reference , and iterator_­category , iterator_­traits<Iterator> shall have the following as publicly accessible members:

using difference_type = typename Iterator::difference_type; 
using value_type  = typename Iterator::value_type; 
using pointer   = typename Iterator::pointer; 
using reference   = typename Iterator::reference; 
using iterator_category = typename Iterator::iterator_category; 

Otherwise, iterator_­traits<Iterator> shall have no members by any of the above names.

は誰もが、これは実装のバグであるかどうか、または私の期待が間違っている理由を説明していただけますか?

+1

私が標準を解釈するので、iterator_cathegoryの唯一の有効なタイプは、input_iterator_tag、output_iterator_tag、forward_iterator_tag、 bidirectional_iterator_tagおよびrandom_access_iterator_tagです。 iterator_cathegoryに別の値がある場合、イテレーターは有効なiterator_cathegoryタイプを持たないため、このイテレーターのiterator_traitsは指定されたメンバーを持たないものとします。 – Johan

答えて

2

また[std.iterator.tags]で、持っている:

It is often desirable for a function template specialization to find out what is the most specific category of its iterator argument, so that the function can select the most efficient algorithm at compile time. To facilitate this, the library introduces category tag classes which are used as compile time tags for algorithm selection. They are: input_­iterator_­tag , output_­iterator_­tag , forward_­iterator_­tag , bidirectional_­iterator_­tag and random_­acces_­iterator_­tag . For every iterator of type Iterator , iterator_­traits<Iterator>​::​iterator_­category shall be defined to be the most specific category tag that describes the iterator's behavior.

namespace std { 
    struct input_iterator_tag { }; 
    struct output_iterator_tag { }; 
    struct forward_iterator_tag: public input_iterator_tag { }; 
    struct bidirectional_iterator_tag: public forward_iterator_tag { }; 
    struct random_access_iterator_tag: public bidirectional_iterator_tag { }; 
} 

intは、これらのタグの一つではないので、iterator_traits<Iter>::iterator_categoryはバックintあなたを与えることはできません。無効なイテレータカテゴリを持つことは、単にiterator_traitsの前提条件に違反していることを示唆しています。これは必ずしもライブラリが失敗しなければならないというわけではありませんが、失敗はライブラリのバグではありません。

しかし、これらの前提条件は[イテレータ]で明示的に指定されているわけではなく、ライブラリセクションの他の部分と同じです。ですから、私は両方のライブラリが正しいと示唆したいと思いますが、iterator_traits<Iter>でメンバーエイリアスを定義しないというlibC++のアプローチはおそらく良いでしょう。

関連する問題