Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ template class with default parameters, and probably metaprogramming

I went into trouble understanding the following codes:

#include <iostream>
using namespace std;

template <class PixType, bool B = PixType::is>
class Test {
public:
    void print() {
        cout << "PixType B=false" <<endl;
    }
};

template <class PixType>
class Test<PixType,true> {
public:
    void print() {
        cout << "PixType B=true" <<endl;
    }
};

class PT {
public:
    static const bool is = false; // here is the magic
};

int main() {
    Test<PT> t;
    t.print();
}

I have 4 questions:

  1. What's the difference between the first template test class(with <> right after template instead of the class name) and the second one(with <> after class name Test).
  2. Why can two same classes(both are named Test) exist at the same time.
  3. In fact, when the is in class PT is set to be true, the program will print out PixType B=true, otherwise PixType B=false, and I don't know the magic here.
  4. I tried to change the second template Test class to be like:

        template <class PixType, bool B= true>
        class Test {
        public:
            void print() {
                cout << "PixType B=true" <<endl;
            }
        };
    

    But the compiler will warn me of name conflict.

I am really new to these template stuff, and got really confused by these lines of codes. And I don't know how to search for this trick. In most articles about C++ templating, they just talk about some basic ideas and usages about template.

Any help will be greatly appreciated.

like image 426
Codinfox Avatar asked Mar 05 '26 14:03

Codinfox


1 Answers

Point 1 What's the difference between the first template test class(with <> right after template instead of the class name) and the second one(with <> after class name Test).

Response The first one is the main class template definition. The second one is a specialization of the class template where the second parameter of the template is true.

If you didn't have the second one, the first one will be used regardless of whether the second parameter of the template is true or false.

Point 2 Why can two same classes(both are named Test) exist at the same time.

Response In your case, the second one is a specialization of the first one. When you use:

Test<int, true> a;

The compiler knows to use the specialization to generate code for Test<int, true>. When you use:

Test<int, false> b;

The compiler know to use the first one to generate code for Test<int, false>.

Point 3 In fact, when the is in class PT is set to be true, the program will print out PixType B=true, otherwise PixType B=false, and I don't know the magic here.

Response As I explained above, when the second parameter is true, the compiler uses the second class template. Otherwise, it uses the first class template. I hope there is no confusion about that any more.

Point 4 I tried to change the second template Test class to be like:

template <class PixType, bool B= true>
class Test {
public:
    void print() {
        cout << "PixType B=true" <<endl;
    }
};

But the compiler will warn me of name conflict.

Response

Class templates can only be specialized, they cannot be overloaded.

template <typename A, typename B> class C1 {};
template <typename A> class C1 {};

The above is not supported by the language.

template <typename A, typename B> class C1 {};
template <typename A> class C1<A, A*> {};

The above is supported by the language. The second class template is a specialization of the first class template.

What you are trying to do is provide a default value for the second parameter but the name used to define the class template is same. The second one is a different class template not a specialization of the first class template.

like image 174
R Sahu Avatar answered Mar 08 '26 21:03

R Sahu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!