Bringing privately inherited Base`s class constructor to the Derived's public scope

67 Views Asked by At

Inheriting a constructor from a private template class in C++ explaining that by using Base::Base; inside Derived we're bringing the type Base injected in Base as Base::Base to scope of Derived and not actual Base's c-tor(s). I'm intersting in whys and hows a bit more deeply than it was covered in question mentioned above.

In snippet below there're 3 template classes MyVector... that are inherited from std::vector. I'm curios why using Super::vector; is not enough to make things work for private and protected cases? Shouldn't it bring vector с-tor to the public of the MyVector...'s scope and thus change access to it like for other members like at and push_back? And also why using Super::vector; is considered as type declaration in question above when it's clearly refers to constructor as cued by C2923 error if we try use it Super::vector with IsAType. Even if it was a type, why language doesn't make it publicly accessed as it does with using Super::iterator;?

#include <vector>

template< class T >
struct IsAType {};

template< class T >
class MyVectorPublic : public std::vector< T >
{
   using Super = std::vector< T >;
   
public:
   using Super::vector;
   
   using Super::at; // function
   using Super::push_back; // function

   using Super::iterator; // type
   // IsAType< Super::vector > t; // 
};

template< class T >
class MyVectorProtected : protected std::vector< T >
{
   using Super = std::vector< T >;

public:
   using Super::vector;
   using stdvec = typename Super::vector;

   using Super::at; // function
   using Super::push_back; // function

   using Super::iterator; // type
   // IsAType< Super::vector > t; // C2923
};
    
template< class T >
class MyVectorPrivate : private std::vector< T >
{
   using Super = std::vector< T >;

public: 
   using Super::vector; 
   using stdvec = typename Super::vector;

   using Super::at; // function
   using Super::push_back; // function

 
   using Super::iterator; // type 
   // IsAType< Super::vector > t; // C2923
};


int main()
{
   auto vecPub = MyVectorPublic< int >::vector(); 
   //auto vecProt = MyVectorProtected< int >::vector(); // C2247
   //auto vecPriv = MyVectorPrivate< int >::vector(); // C2247
   auto vecProt = MyVectorProtected< int >::stdvec();
   auto vecPriv = MyVectorPrivate< int >::stdvec(); 

   auto itPub = MyVectorPublic< int >::iterator();
   auto itProt = MyVectorProtected< int >::iterator();
   auto itPriv = MyVectorPrivate< int >::iterator();
}

error C2247: 'std::vector<int,std::allocator>' not accessible because 'MyVectorProtected' uses 'protected' to inherit from 'std::vector<int,std::allocator>'

error C2247: 'std::vector<int,std::allocator>' not accessible because 'MyVectorPrivate' uses 'private' to inherit from 'std::vector<int,std::allocator>'

error C2923: 'IsAType': 'std::vector<int,std::allocator>::{ctor}' is not a valid template type argument for parameter 'T'

Update: So it seems the real reason is that standart ignores using declaration access modifier when we're talking constructors: http://eel.is/c++draft/namespace.udecl#14 http://eel.is/c++draft/namespace.udecl#16 Please correct me if I'm wrong.

0

There are 0 best solutions below