2017-03-06 20 views
4

次のコードはなぜ有効ですか?次のコードcompiles (IDEOne)ように、構造体のテストは、テストのベクトルが含まれています:それはあるようC++再帰型定義

#include <iostream> 
#include <vector> 

using namespace std; 

struct test { 
    vector<test> a; 
}; 

int main() { 
    // your code goes here 
    test t; 
    if (t.a.size() > 0) 
     return -1; 
    else if (t.a[0].a[0].a.size() > 0) 
     return 1; 
    return 0; 
} 

がどのようにコンパイラが構造体を扱うんt.a[0].a[0].a.size()をテストすることは可能でしょうか? .a[0]の繰り返し回数に制限はありますか?


編集:この質問は、これは未定義の動作であると主張答えを持っていますAre C++ recursive type definitions possible, in particular can I put a vector<T> within the definition of T?

は=>これは>

=を混乱さ、おそらく私の質問は、これはつまるところ、重複

+1

'のstd :: vector'のデフォルトコンストラクタがありませんテンプレート引数が完全修飾名である必要はありません。 – paddy

+1

物事をもっと遠くに押し出すには、 'struct WTF:std :: vector {};'私はPeanoの自然数(https://en.wikipedia.org/wiki/Peano_axioms)を構築するためにそれを使います:D – YSC

+0

(ヒント: 'operator ++()'は '{push_back(* this); return * this;}')です。 – YSC

答えて

2

ですvector<T>には、タイプTの値を知る必要がなくなり、Tは不完全な型になります。基本的には、劇中のメカニズムは、ここではこの宣言と同じです:

struct test { 
    test* start; 
    test* end; 
}; 

コンパイラは、限り、あなたは、いくつかの後の時点でそれを定義することを約束として、任意の型へのポインタを宣言する問題はありません。

テンプレートに基づいて、この動作の変更:あなたはvector<T>testを定義する問題はないが、array<T,Size>あるいはpair<T,K>が問題となる:

struct broken1 { 
    array<broken1,3> a; // Does not compile 
}; 
struct broken2 { 
    pair<broken2,broken2> p; // Does not compile 
};