2016-10-28 7 views
0

をにiterator_traitsは私linked_listテンプレートのフラグメントです。構造体のSTDに「ポインタ」という名前の無いタイプ::ここ<...>

グラム++ 5.4:

list2.cxx:105:66: error: no type named ‘pointer’ in ‘struct std::iterator_traits<linked_list<int>::iterator_base<(linked_list<int, std::allocator<int> >::constantness)1u> >’ 
      typename std::iterator_traits<iterator_base>::pointer operator ->() const { return &(to_obj_node(current_node_) -> object()) ; } 

ICPC:

list.cxx(105): error: incomplete type is not allowed typename std::iterator_traits<iterator_base>::pointer operator ->() const { return &(to_obj_node(current_node_) -> object()) ; } 

その行がなければ、すべてはうまくコンパイルします。

質問です:何が起こる、私は(そのような変更のコードはコンパイルのみで)上記のコードでusing difference_type = typename std::iterator_traits<iterator>::difference_type;をコメントしていたときに。?

==============================================その上============================ res.on.functions/2.5

  1. In particular, the effects are undefined in the following cases:...
    1. if an incomplete type ([basic.types]) is used as a template argument when instantiating a template component, unless specifically allowed for that component.

や歴史discussionPointer_nahの宣言の時点で

+2

[mcve] – Barry

+0

を入力してください。ノード< T >とは何ですか? – wally

+0

'#include 'ですか? –

答えて

1

、それはあなたのコンパイラのいずれかが叫んだ理由だと思われますpointerメンバー。

クラスstd::iterator_traits<iterator_base>は、::の左側で使用されているため、まだインスタンス化されていないため、typename std::iterator_traits<iterator_base>::difference_typeによってインスタンス化されています。例えばインスタンス化が標準ライブラリにtypedef typename Iterator::value_type value_type;次のような行で起こることができる - iterator_traitsの体はその様々なメンバーのtypedefを定義し、そのクラスを使用していますので、これはlinked_list<int>::iterator_baseのインスタンス化をトリガします。

あなたのネストされたクラスでstd::iterator_traits<iterator_base>::pointerの使用はどのような次です。今回はiterator_traits<iterator_base>がすでにインスタンス化されているため、何も実行されず、::pointerが検索されます。しかし、それはまだ宣言されていないので、それは見つけることができません。

あなたはコメントを出したときにusing行を、コードで何ももはやネストされたクラス本体をインスタンス化しないことに注意してください(クラステンプレートのメンバーの体が「いい加減にインスタンス化」されている)ので、これはのための措置することはできませんそのネストされたクラス本体の中の構造体の妥当性に反しています。

+0

オペレータにいくつかのボディを与え、main(){auto iptr = linked_list < int > :: iterator_base()。operator - >(); 0を返します。 }。コメント行で完全にコンパイルします。 –

+0

またはテンプレートリスト。 –

+1

@GreenTreeなぜあなたのケースで失敗するのか説明し、 'using'行をコメントアウトすると失敗しない理由を説明しました。実際に 'iterator_base'をインスタンス化する理由は、' iterator_base'の本体の内部にあるときに、 'iterator_base :: pointer'、' value_type'などを参照できることです(基本クラスで定義します) 。そして、あなたが 'iterator_traits :: pointer'を実行するときには、iterator_traits をインスタンス化し、その時点で可能なtypedefにアクセスするだけです。 –

0
#include <iterator> 

struct OK_1: std::iterator<std::bidirectional_iterator_tag, int> {}; 
using Pointer_1 = typename std::iterator_traits<OK_1>::pointer; 

struct Nah 
{ 
    using Pointer_nah = typename std::iterator_traits<Nah>::pointer; //! 
}; 

auto main() -> int 
{} 

、タイプNahは不完全型です。

iterator_traitsは、そのpointer定義を見つけるために、そのタイプの中を見なければなりません。

しかし、それは、再帰的に、iterator_traits<Nah>の定義が必要です。

など。

しかし、Pointer_nahが宣言された時点で、主なポイント:Nahは不完全です。 不完全なは、クラスが完全に知られていないことを意味します。特にそのサイズはここでは分かりませんので、sizeofに渡すことはできません。

私はここでエラーがタイプstd::iterator_traits<iterator_base>がまだ不完全であり、あなたが::pointerにアクセスする時に、まだそれを提供していないということである

error: incomplete type is not allowed

+0

あなたは私の例を非コメントとコメント "使用"の行でコンパイルしようとしましたか? なぜコードがコンパイルされるのか? –

+0

@GreenTree:テンプレートでは、使用された場合にコンパイルされないあらゆる種類のものを持つことができます。それらを使用するとすぐに、コンパイラは不平を言う。どういうわけか 'iterator_base'を使う' difference_type'宣言は、それが存在すればそれ自身が使用されます。なぜか分かりませんが、実際には 'iterator_base'を使って他の方法で試すことができます。あなたがするとすぐに、それは爆破する。 :) –

+0

質問版の歴史を見て、それからすべてのコード((for each auto:list))をコンパイルします。 –

関連する問題