partial specialization of template class issue!
The following code is confusing me
//partial specialization of vector
template<class t>
class vector
{....
};
template<class t>
//teacher said that this partial specialization will handle all type of pointers
class vector<t*>
...
};
This is confusing me a lot, Suppose t is a char* , as the compiler will first look for the complete specialization as there is no c开发者_JAVA百科omplete specialization here , the partial specialization would be considered. Now it will become char** in partial specialization as t is char*, then it means we are not achieving the functionality that we want. Please Explain in more understandable manner.
When the compiler instantiates vector<char*>
, it matches the following template:
template<class T>
class vector<T*> {
...
};
For this template to produce a class vector<char*>
it needs to be instantiated with T=char
, and this is exactly what the compiler does.
When the compiler sees the type vector<char*>
it will not use T=char*
to instantiate the template, because this would result in the wrong type vector<char**>
. It will use T=char
instead, which results in vector<char*>
. The compiler uses template parameters that will give the correct resulting type.
The compiler will always looks for the match that is most specialized (and will fail if there's ambiguity).
Since char**
matches both patterns:
char** = T* (with T = char*)
char** = T (with T = char**)
and the former is more specialized, that will be chosen. (And since char**
is really a pointer to something, I think "we are not achieving the functionality that we want" is false.)
Edit.
Once the specialization is chosen, all other candidates will be thrown out (recursive substitution will not happen in the matching phase). For instance,
template<class T> struct A {
typedef T type;
static const int value = 0;
};
template<class T> struct A<T*> {
typedef T type;
static const int value = 12;
};
template<class T> struct A<T********> {
typedef T type;
static const int value = 1024;
};
...
A<char**>::type x; // <-- Line X
std::cout << A<char**>::value << std::endl; // <-- Line Y
At Line X and Y, the template A
is to be instantiated. You give the first template parameter as char**
. A
expects either a pattern of T********
or T*
or T
. The 2nd one is the best match, so template<class T> struct A<T*>
will be chosen. The other two will be stroke out.
# FAIL. Not specialized enough. Remove this from consideration.
// template<class T> struct A {
// typedef T type;
// static const int value = 0;
// };
# WIN. Use with T = char*.
template<class T> struct A<T*> {
typedef T type;
static const int value = 12;
};
# FAIL. Does not match char**.
// template<class T> struct A<T********> {
// typedef T type;
// static const int value = 1024;
// };
After performing substitution it becomes
struct A<char**> {
typedef char* type;
static const int value = 12;
};
and Line X and Y shall become
/*A<char**>::type*/ char* x; // <-- Line X
std::cout << /*A<char**>::value*/ 12 << std::endl; // <-- Line Y
(Note:
template<class T> class Vector
is not a partial specialization,
template<class T> class Vector<T*>
this one is.)
template<class t>
//teacher said that this partial specialization will handle all type of pointers
class vector<t*>
{
...
};
vector<char*> v;
Your confusion comes from assuming that the t in <class t>
names the full argument that you give when instantiating. Instead, the argument is matched against <t*>
and so t = char
.
For example, imagine the following specialization:
template <class T> struct Foo {};
template <class T> struct Foo<vector<T> > {}; //specialization for your vector
Foo<vector<int> > f;
Again it chooses the specialization, where vector<int>
is matched against vector<T>
and T = int
.
精彩评论