2011-12-06 3 views
4

次のコードは合法ですか? MSVC 9とg ++ 4.4は反対する:しないg ++の間派生型は、そのベースのネストされた型と同じ名前にできますか?

c:\dev>cl test.cpp 
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 
Copyright (C) Microsoft Corporation. All rights reserved. 

test.cpp 
test.cpp(10) : error C2146: syntax error : missing ';' before identifier 'type' 
test.cpp(10) : error C2761: '{ctor}' : member function redeclaration not allowed 

test.cpp(10) : error C2065: 'type' : undeclared identifier 

struct base 
{ 
    struct derived {}; 
}; 

struct derived : base {}; 

int main() 
{ 
    typedef derived::derived type; 
    return 0; 
} 

MSVCは、型のコンストラクタのためのネストされた名前を混乱させ、不平を言う状況については

$ g++ --version test.cpp 
g++ (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5 
Copyright (C) 2010 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

、私のコードpointerというイテレータが含まれています。イテレーター・インターフェースを提供するために、ネストされたタイプpointerを提供します。これは、それ自体の同義語です。

+0

でエラーなしでコンパイルそれについて。 –

+0

'typedef typename derived :: derived type;'で試してみて、それがうまく動作するかどうか確認してください。 –

+0

申し訳ありませんが、私はあなたのコードを誤解しました。ちなみに、Comeauのコードは違法です( 'typename'の有無にかかわらず)、VC++がここにあると思う傾向があります。 –

答えて

3

Comeauあなたのコードは間違っていると思いますので、型解釈の陰影をつけているコンストラクタ解釈は、標準で義務付けられているものだと思います。ちなみに

struct base 
{ 
    struct derived {}; 
}; 

struct derived : base {}; 

int main() 
{ 
    typedef derived::base::derived type; 
    return 0; 
} 

、その事実を:あなたがアップ明確な曖昧さとあなたは、基本クラスのderivedメンバーにアクセスしようとしているコンパイラに伝える場合

はまだ、あなたのコードは喜んでコンパイルコンストラクタの解釈はちょっと意味が分かります:コンパイラに(スコープ解決演算子を介して)基本クラスのものを参照させることをコンパイラに伝える周知の方法がありますが、その逆を行う構文はありません(あなたがコンストラクタを参照していることをコンパイラに理解させる)。したがって、「デフォルトでのコンストラクタ」の動作はかなり賢明です。


  1. 私は後でそれを調べることが、私は実際に、厄介な名前の問題のこの種は、常に検索する混乱していることを保証しません。
+0

ありがとう! '' 'std :: iterator_traits'''は残念なことにそれに挑戦します。私はそれを専門にしなければならないと思う。 –

+0

@ JaredHoberock:あなたは実際に何をしようとしていますか? –

+0

私は '' boost :: iterator_adaptor'''から派生したポインタラッパー '' 'ポインタ' ''を持っています。ポインタラッパーは、型システム内のメタデータをエンコードします。 –

0

あなたの持っているものは名前の衝突です。 2番目の構造体の名前を構造体derived2に変更します。 そして、あまりにもmain()でこの変更を行います。typedef derived2::derived type; をそれは私が `` `typename```は、非テンプレートコードでは違法である、または少なくともいくつかのコンパイラは文句を言うことを信じているVC++ 6.0

struct base 
{ 
    struct derived {}; 
}; 

struct derived2 : base {}; 


int main() 
{ 
    typedef derived2::derived type; 
    return 0; 
} 
+0

私は、VC++ 6.0との標準適合性についていくつかのコードをチェックしません。:S –

関連する問題