Why should I create a type alias when using the Variadic constructor function?

I have a generic base class that accepts N number of types:

template <typename... Ts>
class Base{};

When using secure inheritance in this base class

template <typename... Ts>
class Derived : protected Base<Ts...>{
   //like so...
};

I would like to additionally include public base class constructors:

template <typename... Ts>
class Derived : protected Base<Ts...>{

   //create an alias
   using Parent = Base<Ts...>;

   //get all constructors as well
   using Parent::Parent; 
};

It works.
However, why should I include an alias Parent?

It doesn't seem like I can get 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 part of the template and it compiles, but this does not look right:

template <typename... Ts>
class Derived : protected Base<Ts...>{

   //get all constructors as well
   using Base<Ts...>::Base; 
};

The reason I don't think this is right is because it does not work on a vector. not compiling:

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; 
};

:
, , , ?

+4
3

Base , using Base<Ts...>::Base<Ts...>; , .

, ,

class Base{
    public:
        Base(){}

        template<typename ... Ts>
        Base(){}
};

using Base<Ts...>::Base<Ts...>?

, using Parent = Base<Ts...>, , using Parent::Parent, Parent, . using Base<Ts...>::Base;.

+2

. , Base<Ts...> Base<Ts...>. Base.

:

template<class...Ts>
struct Base {

};

template<class...Ts>
struct Derived : Base<Ts...>
{
    using Base<Ts...>::Base;
};

, std::vector<...> std::vector, vector

:

template<class...Ts>
struct Derived : std::vector<Ts...>
{
    using std::vector<Ts...>::vector;
};

std:: container! .

+4

using Base<Ts...>::Base<Ts...>; - [namespace.udecl] p5:

- .

, -. .


... :

  • " ". [class.ctor] 1
  • " -, [...]" [class.ctor] p4

, , . :

struct { int m; } x;
decltype(x) // refers to the type of `x` which has no name

-, , .


[class.qual] p2 , qualified-ids ( - -id):

, , - C:

  • (2.1), , -, C, C
  • (2.2) , , , -, simple-template-id ,

C.

, .

, (2.1) OP: while Base , Base, Base<Ts...>. , -, Base<Ts...>, .

, .

template<typename T>
struct foo : T {
    using T::name;
    void name(double);
};

struct name { name(int); };
struct bar { void name(int); };

foo<name> // constructor inheritance?
foo<bar>  // makes a function visible?

clang++ , g++ . CWG 2070

, , , Base OP . , , , . , .

(2.2) Base<Ts...>::Base<Ts...>: - Base<Ts...>. - Base. - Base<Ts...>.


[class.qual] p2.2 Base<Ts...>::Base parent::parent, , . . , .

+1
source

All Articles