Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is template<classTp> bool is_array<Tp[]> a partial specialization for template<class T> bool is_array<Tp>?

How to comprehend that template<typename Tp> bool is_array<Tp[]> = true is a partial specialization for template<typename T> bool is_array<Tp> = true?

Here is the related code snippet:

#include<iostream>

template<typename T>
bool is_array = false;

template<typename Tp>
bool is_array<Tp[]> = true;

int main()
{
    std::cout << is_array<int> << std::endl;
    std::cout << is_array<int[]> << std::endl;
}

I've also noticed that generally speaking, the number of template parameters in the partial template specialization is less than the number of template parameters in the primary template.

The partial specializations often are seen like this:

#include<iostream>

template<typename T, typename U>
class add
{
public:
    add(T x, U y)
    {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
};

template<typename U>
class add<int, U>
{
    public:
    add(int x, U y)
    {
        std::cout << __PRETTY_FUNCTION__ << std::endl;       
    }
};

int main()
{
    add<int, double>(1, 5.0);
    add<char, int>('a', 9);
}
like image 724
John Avatar asked Dec 17 '22 12:12

John


1 Answers

For a template to be a specialization of a primary, it needs to be more specialized than the primary. This basically means that the specialization must match a strict subset of types that the primary can match.

In your case, the specialization would match int[], char[], etc. The primary would also match these types, but the primary would additionally match types like int, char, std::vector<std::string> etc.

When specifying a template argument like this is_array<int[]>, the rules say that the specialization is tried first. In this case, Tp[] can be matched to int[] (basically by substituting int for Tp) and so the specialization is chosen.

When specifying a template argument like this is_array<int>, the specialization is tried first, but it fails to match. So then the primary is tried, and that matches, so the primary template is chosen.

As you've mentioned, it is often the case that the specialization has fewer template parameters. This is not necessary, so long as the rule I mentioned above is applicable, i.e. the specialization must match a strict subset of the types that can be matched by the primary.

In fact, the specialization can even have more template parameters than the primary. Again, the requirement is only that the specialization match a subset of types matched by the primary.

like image 59
cigien Avatar answered May 19 '23 05:05

cigien