次のコードは有効ですか?
struct A
{
struct nested;
};
struct B : public A {};
struct B::nested {};
gcc はそれを受け入れますが、clang は次のエラーで拒否します。
test.cpp:8:14: error: no struct named 'nested' in 'B'
class B::nested {};
~~~^
次のコードは有効ですか?
struct A
{
struct nested;
};
struct B : public A {};
struct B::nested {};
gcc はそれを受け入れますが、clang は次のエラーで拒否します。
test.cpp:8:14: error: no struct named 'nested' in 'B'
class B::nested {};
~~~^
はい、無効です。これが引用です。
セクション 9 パラグラフ 11、強調鉱山:
class-head-nameにnested-name-specifierが含まれている場合、class - specifierは、nested-name-specifierが参照するクラスまたは名前空間で直接宣言されたクラス、またはの要素で以前に宣言されたクラスを参照するものとします。その名前空間のインライン名前空間セット (7.3.1) (つまり、単にusing-declarationによって継承または導入されたものではない)、およびclass-specifierは、前の宣言を囲む名前空間に表示されます。そのような場合、定義のclass-head-nameのnested-name-specifierは、 decltype-specifierで始まってはなりません。
あなたの例では、class-head-nameは tokensB::nested
であり、nested-name-specifier B::
とclass-name nested
で構成されています。クラス指定子は...全体struct B::nested {
です}
。
B には、 という名前のネストされたクラスはありませんnested
。A のみが名前付きのネストされたクラスを持ち、nested
class A::nested { };
正常に動作するはずです
から継承しているため、 に構造体をA
カプセル化していません。nested
B
タイプの作成された構造体からは、構造体の一部であるためB
名前付き構造体にのみ到達できますが、カプセル化されているため、名前付き構造体を構築する責任があります。nested
B
nested
A
nested
全体として、コードは無効です。