tags:

views:

95

answers:

3

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 complete 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.

+2  A: 

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.)

KennyTM
still confusing not understandable by me.you saidchar** = T* (with T = char*) char** = T (with T = char**) now i am supposing that t is char* , now it will become that char** if compiler consider the partial specialization. it will remain char* if compiler consider the following template<class t> class vector {.... };
Zia ur Rahman
@Zia: Which part is confusing you?
KennyTM
i am unable to get the idea , and i desrcirbed above why i am confused please try to understan my above comment
Zia ur Rahman
@Zia: See update.
KennyTM
+2  A: 

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.

sth
Hmm.. how does the compiler decide "`vector<char **>` is the wrong type"?
peterchen
@peterchen: If you say you want a `vector<char*>` (like in `vector<char*> mystorage;`) than a `vector<char**>` would be wrong.
sth
oo yes! your answer is completly helpful i have got the point. most people do not read the question properly and try to answer that question which becomes very very confusing for the asker as you can see the answer of KennyTM his answer is very very complex and hard to understand for a student. so, thank you verymuch.
Zia ur Rahman
how can i contact you each time i have a question??????
Zia ur Rahman
+1  A: 
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.

UncleBens
thank you sir , your answer is completly helpful, i understood what you trying to convey. your answer is according to the question and very helpful. so thank you very much
Zia ur Rahman