'Explicitly calling base class constructor in derived class

May I ask if we are allowed to explicitly call base class constructor in derived class? (if not, why?)

I'm asking this question because I wrote the following toy code and the results confuse me:

class X
{
public:
    void wow()
    {
        cout << "wow\n";
    }
protected:
    X()
    {
        cout << "creating X\n";
    }
    X(int i)
    {
        cout << "creating X with i\n";
    }
};

class Y : protected X
{
public:
    X r = X{ 1 };  // error at this line: (C2248) 'X::X': cannot access protected member declared in class 'X'
};

int main()
{
    Y y;
    y.r.wow();
}

However, if I make a slight modification in class Y, the code actually compiles:

// X defined same as above...

class Y : protected X
{
public:
    X r = { 1 };
};

int main()
{
    Y y;        // creating X
                // creating X with i
    y.r.wow();  // wow
}

I'm using Visual Studio 2022.



Solution 1:[1]

Inheritance doesn’t give full access with protected, you have access to protected field only through the derived class. So you cannot access protected field for your member. In more detail see

Protected_member_access

A protected member of a class is only accessible

[..]

  1. to the members and friends (until C++17) of any derived class of that class, but only when the class of the object through which the protected member is accessed is that derived class or a derived class of that derived class:

Second sample should fail also for same reason (And actually do for clang/gcc Demo). I would say msvc bug.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1