0

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.

Soup Endless
  • 439
  • 3
  • 10
  • Your code compiles fine with other compilers. – ypnos Mar 17 '21 at 11:06
  • @ypnos This's perfectly compialable snippet. The code in question - that cause compilation errors - is comennted with reference to compile-time errors I've transcribed at the bottom of the message as quotes. – Soup Endless Mar 17 '21 at 11:45
  • I don't understand why you would call the constructor like that. `class A : B { using B::B; }` for me means that you have all B constructors available under the name of A. so you wouldn't instantiate with `A::B()`, but simply with `A()`. And this also works for your examples. What am I missing here? – ypnos Mar 17 '21 at 12:06
  • I don't quite catch what do you mean. Either way it's not `why would you do this?`, instead it's `how language works?` in order to deeply understand the language and its concepts. – Soup Endless Mar 17 '21 at 12:39
  • Please explain what exactly you expect `auto vecProt = MyVector*< int >::vector();` to do. – ypnos Mar 17 '21 at 16:08
  • @ypnos I expect that the `vector` in expr `auto vecProt = MyVector< int >::vector();` will be either type or c-tor, thus creatring `std::vector` instance. I was wondering just how much you can bring into scope of `Derived` from `Base` in private inheritance hierachy. As standard state, when you're dealing with `Base`'s c-tor inside `Derived` like this: `using Base::Base;` it ignores access modifiers, so as far as I understood: `Base` c'tors in scope of the `Derived` will hace access modifiers used for inheritance. One more time: I don't use this code anyhow, just curios about C++. – Soup Endless Mar 17 '21 at 16:40

0 Answers0