I have a templated base class that takes an N amount of types:
template <typename... Ts>
class Base{};
When using protected inheritance on that base class,
template <typename... Ts>
class Derived : protected Base<Ts...>{
//like so...
};
I would like to additionally include the public constructors of the base class:
template <typename... Ts>
class Derived : protected Base<Ts...>{
//create an alias
using Parent = Base<Ts...>;
//get all constructors as well
using Parent::Parent;
};
This works.
However, why must I include the Parent
alias?
Is doesn't seem as though I can get the constructors without it. The following attempt does not work:
template <typename... Ts>
class Derived : protected Base<Ts...>{
//get all constructors as well
using Base<Ts...>::Base<Ts...>;
};
error:
clang++ -std=c++1z -o main v.cpp
error: expected ';' after using declaration
using Base<Ts...>::Base<Ts...>;
^
;
1 error generated.
I can cut off the template part, and it compiles, but this does not appear to be correct:
template <typename... Ts>
class Derived : protected Base<Ts...>{
//get all constructors as well
using Base<Ts...>::Base;
};
The reason I don't think it is correct is because it does not appear to work on vector.
does not compile:
template <typename... Ts>
class Derived : protected std::vector<Ts...>{
//get all constructors as well
using std::vector<Ts...>::std::vector;
};
However, using an alias does work.
compiles:
template <typename... Ts>
class Derived : protected std::vector<Ts...>{
//create an alias
using Parent = std::vector<Ts...>;
//get all constructors as well
using Parent::Parent;
};
Question:
Do I have to use an alias to get the same functionally, or is there a way to inline this without creating a new name for the base type?
You don't need a type alias. The problem is that the constuctor of Base<Ts...>
is not called Base<Ts...>
. It's called Base
.
This works:
template<class...Ts>
struct Base {
};
template<class...Ts>
struct Derived : Base<Ts...>
{
using Base<Ts...>::Base;
};
In addition, the name of std::vector<...>
's constructor is not std::vector
, it is vector
This also works:
template<class...Ts>
struct Derived : std::vector<Ts...>
{
using std::vector<Ts...>::vector;
};
However, don't derive from std:: containers! Encapsulate them.
In your example Base
does not have a template constructor so using Base<Ts...>::Base<Ts...>;
is trying to find a constructor that does not exist.
Imagine I had a class like yours
class Base{
public:
Base(){}
template<typename ... Ts>
Base(){}
};
Which constructor would using Base<Ts...>::Base<Ts...>
choose?
The reason that using Parent = Base<Ts...>
works is because when you write using Parent::Parent
you are trying to find a constructor of Parent
that is not templated. It expands to using Base<Ts...>::Base;
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With