Is there any way to increase visibility with a using declaration?

Viewed 162

The following code doesn't compile:

class C
{
    private:

        int m_x;

    protected:

        C(int t_x) : m_x(t_x) { }

};

class D : public C
{
    public:

        using C::C;

};

int main(int argc, char **argv)
{
  D o(0);
}

The compiler's objection is that the constructor for C is declared protected, meaning that I can't access it from main. In other words, it seems like the using declaration drags the original visibility of the identifier with it, despite the fact that it lives in the public block.

Two questions:

  1. Why does this happen? (Both in terms of the rules for how this works, and the rationale for making those rules).
  2. Is there any way I can get around this without explicitly writing a constructor for D?
2 Answers

This is a subtle one. In C++, employing the using keyword on a base class constructor is called inheriting constructors and works differently than what a using keyword typically does. Specifically, note that

If overload resolution selects an inherited constructor, it is accessible if it would be accessible when used to construct an object of the corresponding base class: the accessibility of the using-declaration that introduced it is ignored.

(Emphasis mine. Source)

In other words, the fact that you've included the using declaration in a public section doesn't actually make those constructors public.

I believe that, in this case, you may have to define your own constructors to match the base type constructors.

statement using C::C; is not about increasing visibility, but, about since c++11 feature called inheriting constructors, making constructor of base class C invoking when derived D is constructed. You cant change access modifier of constructor that way. But, you can change access modifier, of any function by explicitly redeclaring it in a derived class with the different access modifier.

Related