[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Template specialization - strange behavior
From: |
Klaus Barthelmann |
Subject: |
Template specialization - strange behavior |
Date: |
Wed, 04 Feb 2004 13:49:14 +0100 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.0) Gecko/20020623 Debian/1.0.0-0.woody.1 |
Hi!
I am not quite sure whether the following is a bug in g++-3.3.2 or a
language feature. (I find Stroustrup's book rather unclear in this
respect.) However, it looks very strange.
Let me introduce the well-known stack as an example:
template<class T> class Stack {
struct Link {
T item;
Link* next;
};
Link* first;
public:
Stack() { first = 0; }
void push(T const& item);
T pop();
};
It is implemented as a linked list. Now I try to specialize it for
pointer types such that they are all derived from a single
implementation (for type void*):
template<class T> class Stack<T*> : private Stack<void*> {
public:
typedef Stack<void*> Base;
Stack() : Base() { }
~Stack() { ~Base(); }
void push(T* const& item) { Base::push(item); }
T* pop() { return static_cast<T*>(Base::pop()); }
};
The base class refers to the general template.
This, however, gives an error message:
stack.cc:71: error: base class `Stack<void*>' has incomplete type
It does not help to move the typedef out of the class:
typedef Stack<void*> Base;
template<class T> class Stack<T*> : private Base {
...
};
On the contrary, it does help to define a variable (!!):
Stack<void*> dummy;
template<class T> class Stack<T*> : private Stack<void*> {
// same as above
};
It also helps to introduce a specialization for type void* first:
template<> class Stack<void*> {
struct Link {
void* item;
Link* next;
};
Link* first;
public:
Stack() { first = 0; }
void push(void* const& item);
void* pop();
};
However, as long as I do not care to remove the "const&" in the
parameter to push (because it is cheaper to copy the pointer), this is
exactly the same as the code the compiler should produce from the
general template. I think it should be able to figure this out for
itself. Is g++ just too lazy?
Best regards
Klaus
Klaus Barthelmann, Institut f"ur Informatik, Johannes
Gutenberg-Universit"at, 55099 Mainz,
eMail: address@hidden,
WWW: htp://www.informatik.uni-mainz.de/~barthel/
template<class T> class Stack {
struct Link {
T item;
Link* next;
// ~Link() { delete next; }
};
Link* first;
public:
Stack() { first = 0; }
// ~Stack() { delete first; }
void push(T const& item);
T pop();
};
template<class T> void Stack<T>::push(T const& item)
{
Link* list = new Link;
list->item = item;
list->next = first;
first = list;
}
template<class T> T Stack<T>::pop()
{
Link* list = first;
first = first->next;
T item = list->item;
delete list;
return item;
}
#ifdef SPECIALIZE
template<> class Stack<void*> {
struct Link {
void* item;
Link* next;
// ~Link() { delete next; }
};
Link* first;
public:
Stack() { first = 0; }
// ~Stack() { delete first; }
void push(void* const& item);
void* pop();
};
void Stack<void*>::push(void* const& item)
{
Link* list = new Link;
list->item = item;
list->next = first;
first = list;
}
void* Stack<void*>::pop()
{
Link* list = first;
first = first->next;
void* item = list->item;
delete list;
return item;
}
#else
//Stack<void*> dummy; //!??
#endif
template<class T> class Stack<T*> : private Stack<void*> {
public:
typedef Stack<void*> Base;
Stack() : Base() { }
// ~Stack() { ~Base(); }
void push(T* const& item) { Base::push(item); }
T* pop() { return static_cast<T*>(Base::pop()); }
};
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Template specialization - strange behavior,
Klaus Barthelmann <=