Home > database >  visibility of a class data member in a nested class?
visibility of a class data member in a nested class?

Time:11-21

AFAIK, data member of enclosing class are also visible in nested class.

struct A {
    struct B {
        int arr[n];  // how come n is not visible here, but it is visible in next statement.
        int x = n;
    };

    static const int n = 5;
};

see live demo here

CodePudding user response:

how come n is not visible here, but it is visible in next statement.

Because int x = n; is a complete class context while int arr[n]; is not. This can be understood from class.mem which states:

6) A complete-class context of a class is a:

6.4) default member initializer

within the member-specification of the class. [ Note: A complete-class context of a nested class is also a complete-class context of any enclosing class, if the nested class is defined within the member-specification of the enclosing class. — end note ]

7) A class is considered a completely-defined object type ([basic.types]) (or complete type) at the closing } of the class-specifier. The class is regarded as complete within its complete-class contexts; otherwise it is regarded as incomplete within its own class member-specification.

(emphasis mine)

Note that the n inside int arr[n]; is part of the type of the array but the above quoted statement doesn't allow n to be used as part of a type of a non-static data member and hence the error. For the same reason, we will get the same error if we wrote:

struct A {
    struct B {
          
        int x = n;
//----------------------v--------->same error as before
        std::array<int, n> arr; 
    };

    static constexpr int n = 5;
};

CodePudding user response:

My answer is more like intuition of why this is so:

In int arr[n] n is used in definition of a filed, while in int x = n n is used to initialize a field. It is like B() : x(n) {}.

Think of the following example:

struct A {
    struct B {
        int arr[n];
        int x = n;
    };
    static constexpr int n = offsetof(B, x);
};

Here the value of n is dependent on the size of arr and size of the arr is dependent on n. It is a cross dependency. Therefore the struct is not well defined.

If the rules of the C was so that your use case be legal, then this should also be legal, which can't be. However, it still allow us to use offsetof in initialization, because why not?

CodePudding user response:

Something about evaluation variable in left-hand side of assignment, not a computer language expert, the following worked.

#include <iostream>
using namespace std;

    struct A {
        struct B {
            int *arr = new int[n]();
            int x = n;
        };
    
        static const int n = 5;
    };
    int main() {
      cout << "Hello World!";
      return 0;
    }
  • Related