Problem doing an explicit specialization for a template member

I'm trying to define a template member inside a template class. Here is a fragment of the header file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// queuetmp.h -- Queue class template (for project Exercise 14.3.cbp)

#ifndef QUEUETMP_H_
#define QUEUETMP_H_

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);
    };
// private class members
    Node* front; // pointer to front of Queue
    Node* rear; // pointer to rear of Queue
    int items; // current number of items in Queue
    const int qsize; // maximum number of items in Queue
    DeepCopy<Type> test; // object member (if the type parameter is a pointer to something, it will generate the corresponding docopy function)
// preemptive definitions to prevent public copying (inline)
    Queue(const Queue& q) : qsize(0) { }
    Queue& operator=(const Queue& q) { return *this;}
public:
    Queue(int qs = Q_SIZE); // create queue with a qs limit (default constructor)
    ~Queue();
    bool isempty() const;
    bool isfull() const;
    int queuecount() const;
    bool enqueue(const Type& item); // add item to end
    bool enqueue(const Type* item); // version for pointers (to avoid shallow copying)
    bool dequeue(Type& item); // remove item from front
    bool dequeue(Type* item);
};


OK. 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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 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. (line 12 on the second fragment).

I can't figure out what I'm doing wrong. Any help?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>

template < typename A > struct queue
{
   template < typename B > struct deep_copy_helper
   { void do_copy( B& dest, const B& srce ) ; } ;

   template < typename B > struct deep_copy_helper<B*> // specialization for pointers
   { void do_copy( B*& dest, const B* srce ) ; } ;

   deep_copy_helper<A> test_helper ;
};

template < typename A > template < typename B >
void queue<A>::deep_copy_helper<B>::do_copy( B& dest, const B& srce )
{ std::cout << "generalization\n" ; dest = srce ; }

template < typename A > template < typename B >
void queue<A>::deep_copy_helper<B*>::do_copy( B*& dest, const B* srce )
{ std::cout << "specialization for pointer\n" ; dest = srce ? new B(*srce) : nullptr ; }

int main()
{
    queue<int> queue_of_values ;
    int a ;
    int b = 99 ;
    queue_of_values.test_helper.do_copy(a,b) ; // generalization

    queue<int*> queue_of_pointers ;
    int* c = nullptr ;
    int* d = &a ;
    queue_of_pointers.test_helper.do_copy(c,d) ; // specialization for pointer
    std::cout << *c << '\n' ; // 99
    delete c ;
}
Thanks for your answer! Why the B*& thing instead of simply B*? Isn't it redundant?
> Why the B*& thing instead of simply B*?

Modify the code -
change void do_copy( B*& dest, const B* srce )
to void do_copy( B* dest, const B* srce )
- and run the program. And you would have your answer.
Topic archived. No new replies allowed.