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.