Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defining sub-structure of sub-class inside parent class

Consider the following snippet of code:

class MyClass
{
private:
    struct PrivateClass
    {
        struct SubStruct;
    };

public:
    struct PrivateClass::SubStruct {};

private:
    PrivateClass::SubStruct member;
};

MSVC and gcc compile this code without any errors. clang, however, produces the following error:

<source>:10:26: error: non-friend class member 'SubStruct' cannot have a qualified name
    struct PrivateClass::SubStruct {};

So, who's right? Is this a clang bug?

like image 241
pure cuteness Avatar asked Nov 14 '19 13:11

pure cuteness


2 Answers

According to [class]/11 in the C++ 17 Standard:

If a class-head-name contains a nested-name-specifier, the class-specifier shall refer to a class that was previously declared directly in the class or namespace to which the nested-name-specifier refers, or in an element of the inline namespace set (10.3.1) of that namespace (i.e., not merely inherited or introduced by a using-declaration), and the class-specifier shall appear in a namespace enclosing the previous declaration. In such cases, the nested-name-specifier of the class-head-name of the definition shall not begin with a decltype-specifier.

So it seems the clang compiler is right.

like image 98
Vlad from Moscow Avatar answered Sep 30 '22 14:09

Vlad from Moscow


Standard (latest draft) says:

[class.nest]

If class X is defined in a namespace scope, a nested class Y may be declared in class X and later defined in the definition of class X or be later defined in a namespace scope enclosing the definition of class X.

In this example, the class SubStruct that is declared in the class PrivateClass is defined in neither later in PrivateClass nor later in a namespace scope (but rather, later in a class scope of the outer MyClass). Nor is PrivateClass itself defined in a namespace scope.

Unless there is another rule allowing this, the definition of the sub-nested class as in the example is not at least explicitly allowed. Clang seems to be correct.

like image 41
eerorika Avatar answered Sep 30 '22 15:09

eerorika