Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why must we specify template arguments for template base class when calling its constructor? [duplicate]

I was porting some code from MSVC(without permissive-) to linux and I learned that if you call constructor of a template base class in initializer list of your class you must specify all the template parameters or you get an error. Seems kind of redundant, since if you make a mistake in retyping the template parameters it is a hard error:

error: type 'Base<int, true>' is not a direct or virtual base of 'Derived'

full code here:

template <typename T, bool has_x>
struct Base
{
    Base(T t): t_(t){
    }
    T t_=0;
};



template <typename T>
class Derived : public Base<T, false>
{
public:
    // : Base<T, true> is hard error
    Derived(const T& t) : Base<T, false>(t) {}
};

int main()
{
    Derived d(47);
}

Is there a strong reason for this, or just standardization process never took time to special case this use case?

like image 255
NoSenseEtAl Avatar asked Jun 24 '20 13:06

NoSenseEtAl


People also ask

Why do we use template template parameter?

Why we use :: template-template parameter? Explanation: It is used to adapt a policy into binary ones.

What is template What is the need of template declare a template class?

Templates in c++ is defined as a blueprint or formula for creating a generic class or a function. To simply put, you can create a single function or single class to work with different data types using templates. C++ template is also known as generic functions or classes which is a very powerful feature in C++.

When class is there why do we need template in C++?

Templates are the mechanism by which C++ implements the generic concept. Simply, they allow you to pass data type as a parameter so that you don't need to write the same code for different data types.

What is template class explain the advantages of template class?

Definition. As per the standard definition, a template class in C++ is a class that allows the programmer to operate with generic data types. This allows the class to be used on many different data types as per the requirements without the need of being re-written for each type.


1 Answers

You only need to do that when Derived is a template and the type of the base depends on its template parameters.

This compiles, for example:

template <typename T>
class Derived : public Base<int, false>
{
public:
    Derived(const T& t) : Base(t) {}
};

As far as I know, here (in member initializer list) Base is actually the injected-class-name of Base<...>, inherited from it like everything else.

And if the type of the base does depend on the template parameters, its inherited injected-class-name becomes inaccessible (at least directly), just like any other member inherited from it.

For a member variable/function, you'd add this-> to access it, but for a type member you need Derived:::

template <typename T>
class Derived : public Base<T, false>
{
public:
    Derived(const T& t) : Derived::Base(t) {}
};
like image 93
HolyBlackCat Avatar answered Oct 13 '22 00:10

HolyBlackCat