Home > Mobile >  c primer plus Partial Specializations question
c primer plus Partial Specializations question

Time:06-26

In the "Partial Specializations" section of chapter 14 of C Primer Plus:

Without the partial specialization, the second declaration would use the general template, interpreting T as type char *.With the partial specialization, it uses the specialized template, interpreting T as char.
The partial specialization feature allows for making a variety of restrictions. For example, you can use the following:

// general template
template <class T1, class T2, class T3> class Trio{...};

// specialization with T3 set to T2
template <class T1, class T2> class Trio<T1, T2, T2> {...};

// specialization with T3 and T2 set to T1*
template class Trio<T1, T1*, T1*> {...};

Given these declarations, the compiler would make the following choices:

Trio<int, short, char *> t1; // use general template
Trio<int, short> t2; // use Trio<T1, T2, T2>
Trio<char, char *, char *> t3; // use Trio<T1, T1*, T1*>

But when I try this:

template <typename T1, typename T2, typename T3>
class Base
{
public:
    Base()
    {
        cout << "general definition" << endl;
    }
};

template <typename T1, typename T2>
class Base<T1, T2, T2>
{
public:
    Base()
    {
        cout << "T1 and T2 definition" << endl;
    }
};

template <typename T1>
class Base<T1, T1, T1>
{
public:
    Base()
    {
        cout << "T1 definition" << endl;
    }
};

int main()
{
    Base<int, char, double> b1;
    Base<int, char, char> b2;
    Base<int, char> b3;
    Base<int, int, int> b4;
    Base<int> b5;
    return 0;
}

I get errors in Base<int, char> b3 and Base<int> b5:

wrong number of template arguments (2, should be 3)
wrong number of template arguments (1, should be 3)

My question is: When we use partial specializations, if we use a type parameter to initialize another, can we omitting the repetitive part?

My compiler parameters:

D:\MinGw-x64\mingw64\bin\g  .exe 'c:\Users\33065\Desktop\study\C   Primer Plus source code\*.cpp', '-o', 'c:\Users\33065\Desktop\study\C   Primer Plus source code/main.exe', '-std=c  11', '-g', '-m64', '-Wall', '-static-libgcc', '-fexec-charset=GBK', '-D__USE_MINGW_ANSI_STDIO'

CodePudding user response:

A partial specialization will expect as many template arguments as the base template mandates ("base" meaning the unspecialized declaration of your class template, NOT the type named Base). A solution to your problem would be to define the base template as:

template <typename T1, typename T2 = T1, typename T3 = T2>
class Base
{
public:
    Base()
    {
        cout << "general defination" << endl;
    }
};

Since specializations can't have defaulted template arguments, this makes the base template trickle down non-defined parameters to the rest of the typelist. Hence you can write things like:

Base<T1> b1; // this will be Base<T1, T1, T1>

and have each undefined type equate to the previous type.

Demo

  • Related