Templates instantiation in C++
I am confused by how C++ instantiate temp开发者_运维百科late. I have a piece of code:
template <class T, int arraySize>
void test1(T (&array)[arraySize])
{
cout << typeid(T).name() << endl;
}
template<class T>
void test2(T &array)
{
cout << typeid(T).name() << endl;
}
int main()
{
int abc[5];
test1(abc);
test2(abc);
return 0;
}
Here are my questions:
1. How does the size of array abc is passed to test1 (the parameter arraySize )? 2. How does C++ compiler determine the type of T in the two templates?- There is no parameter passing in the normal sense, since template parameters are resolved at compile time.
- Both
arraySize
andT
are inferred from the type of thearray
parameter. Since you pass anint[5]
,arraySize
andT
become5
andint
, respectively, at compile time.
If, for example, you declared int* abc = new int[5];
, your compiler would barf at the point you try to call test1(abc)
. Apart from a basic type-mismatch, int*
doesn't carry enough information to infer the size of the array.
It is called template argument deduction.
The type of abc
at call-site is : int(&)[5]
which has two info combined: int
and 5
. And the function template accepts argument of type T(&)[N]
, but the argument at call-site is, int(&)[5]
, so the compiler deduces that T
is int
and N
is 5
.
Read these:
- The C++ Template Argument Deduction (at ACCU)
- Template argument deduction (C++ only) (at IBM)
In test1 the compiler creates a template with T[arraySize] being its form. When you call test1(abc) you are providing an input argument of type int[5] which the template matcher automatically matches.
However, if you were to write
int n=10;
int *abc = new int[n];
test1(abc);
test1<int,n>(abc);
then the compilation would fail and the compiler would claim that it has no template matching the test1(abc) function call or the test1< int,n >(abc) function call.
This is because the size of abc is now dynamically allocated and so the type of abc is a pointer which has a different type and hence no template could be matched to the above two calls.
The following code shows you some types
#include <iostream>
using namespace std;
template <class T> void printName() {cout<<typeid(T).name()<<endl;}
int main()
{
printName<int[2]>(); //type = A2_i
printName<int*>(); //type = Pi
getchar();
return 0;
}
I'd also add to what Nawaz says: the theory is type inference.
精彩评论