2

I was trying to understand Template Partial and Full Specialization and have this below code:

#include <iostream>
using namespace std;

//Template in C++is a feature. We write code once and use it for any data type including user defined data types.
//What if we want a different code for a particular data type - Template Specialization
template <class T, class Y>
void fun(T a, Y b)
{
    cout << "The main template fun(): " << a << " " <<  b << endl;
}
//If a specialized version is present, compiler first checks with the specialized version and then the main template.
//Compiler first checks with the most specialized version by matching the passed parameter with the data type(s) specified in a specialized version.
template<>
void fun(const char* a, const char* b)
{
    cout << "Specialized Template for int type: " << a << " " <<  b << endl;
}
//Partial specialization allows to specialize only some arguments of a class template, as opposed to explicit full
template<class T>
void fun(T a, int b)
{
    cout << "Partial Template specialization for int type: " << a << " " << b << endl;
}
int main()
{
    fun<int, int>('a', 10);
    fun< const char*, const char*>("Hello", "Morning");
    fun<float, float>(10.14, 19.89);
}

Note that in main I am specifying the data types and below is the output:

The main template fun(): 97 10
Specialized Template for int type: Hello Morning
The main template fun(): 10.14 19.89  

But when I execute the main code below way:

int main()
{
    fun('a', 10);
    fun("Hello", "Morning");
    fun(10.14, 19.89);
}

This is the output I get:

Partial Template specialization for int type: a 10
Specialized Template for int type: Hello Morning
The main template fun(): 10.14 19.89 

So what does the actual C++ Template Partial / Full specialization states - do we need to specify the data types in template argument to invoke - also in many websites I have seen following signature for Partial specialization:

template<class Y, const char*>
void fun(Y a, const char* b)

Rather than

template<class Y>
void fun(Y a, const char* b)

Similarly for full specialization - what is the exact way to write and call Partial / Full template specialized function / class?

cigien
  • 57,834
  • 11
  • 73
  • 112
Programmer
  • 8,303
  • 23
  • 78
  • 162

1 Answers1

0

The comments cover the general principles, but there are specific questions here worth answering. First, a lemma: the template parameters of a function template need not be related to its parameter types:

template<class T>
T make_1() {return T(1);}
auto v=make_1<std::vector<std::string>>(); // {""}
template<class T,class U>
void f(std::conditional_t<sizeof(T)<sizeof(U),int,long> i);

This is why your “partial specialization” is not a candidate for fun<int, int>(…). The template arguments aren’t just instructions for how to build the parameter list one by one, but rather must match the actual template parameters for the function template in question. There’s only one of those, so they don’t match. True partial specializations still use the primary template’s template parameter list; they just match against certain patterns in the list of arguments for it.

Meanwhile,

template<class Y, const char*>
void fun(Y a, const char* b)

is valid but doesn’t mean what you think for the same reason: const char* in the template parameter list introduces an unnamed (non-type) template parameter of type const char*, so that you’d have to use it like

char global;
void g() {fun<char,&global>('a',"foo");}

(with no deduction for Y!), only to have that &global ignored entirely,

Davis Herring
  • 36,443
  • 4
  • 48
  • 76