Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested class using declaration and access modifiers

while compiling some code that I ran into a compiler error that seemed strange to me and relates to inheritance, nested classes, using declarations, and access modifiers.

Basically, the intention is for a derived type to expose a nested protected class of a base type.

The the following short example to demonstrate the issue:

class Base
{
protected:

    struct Nested
    {
        enum value_enum
        {
            val = 0,
            val2,
            val3
        };
    };

};

class Derived : public Base
{
public:

    using Base::Nested;
};


int main(int argc, char** argv)
{
    //Base::Nested aa; // error, as (I) expected
    //Base::Nested::value_enum ab; // error, as (I) expected

    Derived::Nested ba; // works, as (I) expected
    Derived::Nested::value_enum bb; // MSVC error, as (I) did not expect


    return 0;
}

See live.

MSVC11 (v11.00.61030) chokes on this code with the following error:

error C2248: 'Base::Nested' : cannot access protected struct declared in class 'Base'

Both GCC and Clang compile this properly, so without the ability to quote the relevant parts from the standard, I would argue this is an MSVC bug.

Is there a way around this with MSVC?

like image 329
namezero Avatar asked Sep 07 '15 10:09

namezero


People also ask

Which access modifiers we can give to nested class?

A nested class can be declared with any access modifier, namely private, public, protected, internal, protected internal, or private protected.

How do you declare a nested class in C++?

This is given as follows. class A { public: class B { private: int num; public: void getdata(int n) { num = n; } void putdata() { cout<<"The number is "<<num; } }; }; In the function main(), an object of the class A and class B is defined. Then the functions getdata() and putdata() are called using the variable obj.

What is nested class explain with proper example?

A nested class is a member and as such has the same access rights as any other member. The members of an enclosing class have no special access to members of a nested class; the usual access rules shall be obeyed. For example, program 1 compiles without any error and program 2 fails in compilation.

How do I access static nested classes?

And like static class methods, a static nested class cannot refer directly to instance variables or methods defined in its enclosing class: it can use them only through an object reference. They are accessed using the enclosing class name. To instantiate an inner class, you must first instantiate the outer class.


1 Answers

For MSVC the following workaround works:

class Derived : public Base
{
    public:

    using Base::Nested;
    typedef Base::Nested::value_enum value_enum; // add this
};

int main(int argc, char** argv)
{
    //Base::Nested aa; // error, as (I) expected
    //Base::Nested::value_enum ab; // error, as (I) expected

    Derived::Nested ba; // works, as (I) expected
    Derived::value_enum bb = Derived::value_enum::val; // now works in MSVC


    return 0;
}
like image 156
M. Bogdanov Avatar answered Oct 24 '22 20:10

M. Bogdanov