2013-11-14 12 views
7

このコードは有効ですか?C++(11)?複数の継承で隠された入れ子クラス

struct Base { 
    template <typename> 
    struct nested; 
}; 
struct Derived1 : Base { }; 
struct Derived2 : Base { }; 
struct Derived3 : Derived1, Derived2 { }; 

typedef Derived3::nested<int> xxx; 

私は上記のコードを使用してコンパイルに失敗し

知っ:

  • アップルLLVM 5.0(打ち鳴らす-500.2.75)を
  • クラン3.4

しかし、それは正常にコンパイルします:

0また
  • のgcc 4.9.0 20131110(実験)
  • のgcc 4.8

、私はすなわち

struct Base { 
    struct nested; 
}; 
... 
typedef Derived3::nested xxx; 

、非テンプレート型にnestedタイプを変更した場合、それは動作します上記のコンパイラを使用してください。

[編集] も何も変わりませんテンプレートエイリアスにnestedテンプレート構造体を変更します。

template <typename> struct dependent { struct type; }; 
struct Base { 
    template <typename T> 
    using nested = typename dependent<T>::type; 
}; 

上記のコンパイラでも同じ結果が得られます。 N3242から [エンド編集]

§10.1[class.mi]

クラスが複数回間接基本クラスとすることができ、直接的および間接的な基本クラスとすることができます。そのようなクラスではできることは限られています。直接基底クラスの非静的データメンバーおよびメンバー関数は、派生クラスのスコープ内で参照することはできません。ただし、静的メンバー、列挙型および型は明白に参照できます。

私はそれはコードが有効でなければならないことを意味し考えるが、私はよく分かりません。

+0

私はバグ(?)がまだclang 5.0に残っているように見えるので、OPによって満たされた[バグレポート](https://bugs.llvm.org/show_bug.cgi?id=17929)(id 17929)を探しました.1。残念ながら、何の答えもありませんでした。 – Caninonos

答えて

0

あなたがタイプではないメンバーの話をしているので、定義があいまいになる理由を見ることができない(それは非常に強く、標準にこだわっ)

GCCは、より有用/右のいずれかで結構です「ネストされた」と他の基地に「ネストされた」場合、それは間違っているだろう

:自分の名前はC++で等しい場合とタイプは補遺

(名前が関与し、このようなタイプのいくつかのマングルされた形態である)が等しいです異なっていた。これは構造体であり、型定義ではなく、使用しています(スコープあり)

GCCは、何かあいまいな場合は泣いてしまいます。そうでない場所でも雌犬にしたい場合は、-pedanticで試してみてください。私は、GCCがただ許可しているとしても、これを拒絶すべき理由は見当たりません。

+0

私はあなたの補遺を理解しているか分かりません。たとえば、ネストされたものがテンプレート構造体の代わりにC++ 11のテンプレートエイリアスだった場合、コードがあいまいである可能性がありますか? –

+0

@LouisDionneはい、別のものに別名を付けることができたからです。同じルールが適用されるため、解析中のメンバーとして扱われます。ダイヤモンドの問題は、使用したい別名を頭に入れてしまいます。 –

+0

@LouisDionne私は質問に答えましたか?... –

関連する問題