Search code examples
c++inheritanceconstructorusing-declaration

Private using declaration of base constructor is not private


The using declaration for the base constructor is private, but the class can still be constructed. Why?

Accessibility works differently for the operator[]'s using declaration which must be public.

#include <vector>

template<typename T>
class Vec : std::vector<T>
{
private:
    using std::vector<T>::vector;       // Works, even if private. Why?
public:
    using std::vector<T>::operator[];   // must be public
};

int main(){
    Vec<int> vec = {2, 2};
    auto test = vec[1];
}

What if I wanted the constructor to be private? Could it be done with a using declaration?


Solution

  • Using-declarations for base class constructors keep the same accessibility as the base class, regardless of the accessibility of the base class. From [namespace.udecl]:

    A synonym created by a using-declaration has the usual accessibility for a member-declaration. A using-declarator that names a constructor does not create a synonym; instead, the additional constructors are accessible if they would be accessible when used to construct an object of the corresponding base class, and the accessibility of the using-declaration is ignored

    emphasis added

    In plain English, from cppreference:

    It has the same access as the corresponding base constructor.

    If you want the "inherited" constructors to be private, you have to manually specify the constructors. You cannot do this with a using-declaration.