3

I'm trying to define a template member inside a template class.

Here is a fragment of the header file:

template <typename Type>
class Queue
{
private:
// class scope definitions
    // Node is a nested structure definition local to this class
    struct Node {Type item; struct Node* next;};
    enum {Q_SIZE = 10};
    template <typename Type2> class DeepCopy // template member
    {
    public:
        void docopy(Type2& d, const Type2& s);
    };
...

So the template member is defined but I want to make an explicit specialization for the docopy method so it deep-copies when the type is a pointer. I'll put another fragment from the header file with the method template and the specialization:

// template member
template <typename Type>
    template <typename Type2>
void Queue<Type>::DeepCopy<Type2>::docopy(Type2& d, const Type2& s)
{
    d = s;
}

// template member specialization for pointers
template <typename Type>
    template <typename Type2>
void Queue<Type*>::DeepCopy<Type2*>::docopy(Type2* d, const Type2* s)
{
    if (s)
        d = new (*s);
    else
        d = 0;
}

The compiler sends me the following error: expected initializer before '<' token.

I can't figure out what I'm doing wrong. Any help?

jww
  • 97,681
  • 90
  • 411
  • 885
Kurospidey
  • 393
  • 1
  • 4
  • 18
  • 1
    I don't think this can work this way. You'd need to fully specialize the class for pointer types. The problem with your last definition is that `Queue` is an incomplete type. – jrok Sep 09 '12 at 12:39
  • @jrok yep, it seems flawed from the beginning. Thanks for clarifying. – Kurospidey Sep 09 '12 at 12:50

2 Answers2

2

For your example you should

  1. Partial specialize Queue class for T*.
  2. In partial specialization of Queue<T*> write definition of struct DeepCopy.
  3. Write specialization of Queue<T*>::DeepCopy for U*.
  4. Write function Queue<T*>::DeepCopy<U*>::docopy.
jww
  • 97,681
  • 90
  • 411
  • 885
ForEveR
  • 55,233
  • 2
  • 119
  • 133
  • Thanks for your answer. I was trying to avoid as much code duplication as possible. Maybe I should try PiotrNycz advice and define the DeepCopy class template outside the Queue template. – Kurospidey Sep 09 '12 at 12:57
  • Hi again. In the example with the template as one of the parameters, why do you define a new template member inside Queue? Also, how do I do if I want to add one member object in Queue (the object being of the class DeepCopy or DeepCopy? I'm having problems understanding this. – Kurospidey Sep 09 '12 at 14:20
  • @Kurospidey why object? Functions in DeepCopy are static in my example. I define template struct in class, since your example use such method. I am confused, WHY in your class Queue struct DeepCopy is template struct, and not use template parameter T. – ForEveR Sep 09 '12 at 14:22
  • The webmaster broke the link to *Simple example, `http://liveworkspace.org/code/f6505e316e15470b7872a5922c24eef7`*. It takes us to a homepage hocking warez... – jww Jul 30 '15 at 05:19
2

You should write your DeepCopy outside Queue as a top level template. Only use it inside your Queue.

   template <typename T>
   class Queue { 
      DeepCopy<T> myCopy;
      ....
          myCopy.doCopy(n.item, newItem);
PiotrNycz
  • 23,099
  • 7
  • 66
  • 112
  • hi. :) I'm having trouble with this. I misunderstood your prior idea and obviously implemented it badly. Gonna try it now! – Kurospidey Sep 09 '12 at 13:00
  • I will improve my previous answer when I will return to my computer. Now i am writing from my mobile device and it is not easy to write a lot of code. – PiotrNycz Sep 09 '12 at 13:06
  • I'm having a problem with your approach. Or maybe I don't understand it well. Being Queue a template, DeepCopy will take whatever the type is in Queue, so if Queue takes a pointer, DeepCopy will take a pointer too, aplying it to the generic template T. But if you put DeepCopy , then it always takes the specification. Am I wrong? – Kurospidey Sep 09 '12 at 14:05
  • No. The all magic is that for e.g. Queue it will be used DeepCopy. And for DeepCopy the specialization for pointers will be taken. Just try and to be sure put some cout<<__LINE__< – PiotrNycz Sep 09 '12 at 15:04
  • Just to verify, is this answer saying to not have `DeepCopy` as a nested/member class of `Queue` and instead use a composite object of `DeepyCopy` in `Queue`? If so, why is that? – Dennis Jul 29 '13 at 23:38
  • 1
    @Dennis Because in C++ functions (member functions as well) cannot be partially specialized, only classes can be partially specialized. This causes also that member template classes cannot be specialized if they are member of another template. That was why I advised to move this member template class outside of enclosing class. – PiotrNycz Jul 30 '13 at 18:50