By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,537 Members | 929 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,537 IT Pros & Developers. It's quick & easy.

Problem declaring pointer of netsted class inside template ?

P: n/a
Can anybody tell me what is wrong with declaration of pointer p ?

template<class Tclass Stack {
struct Link {
T* data;
Link* next;
Link(T* dat, Link* nxt)
: data(dat), next(nxt) {}
}* head;
public:
Stack() : head(0) {}
~Stack();
void push(T* dat) {
head = new Link(dat, head);
}
T* peek() const {
return head ? head->data : 0;
}
T* pop();
// Nested iterator class:
class iterator; // Declaration required
friend class iterator; // Make it a friend
class iterator { // Now define it
Stack::Link* p;
public:
iterator(const Stack<T>& tl) : p(tl.head) {}
// Copy-constructor:
iterator(const iterator& tl) : p(tl.p) {}
// The end sentinel iterator:
iterator() : p(0) {}
// operator++ returns boolean indicating end:
bool operator++() {
if(p->next)
p = p->next;
else p = 0; // Indicates end of list
return bool(p);
}
bool operator++(int) { return operator++(); }
T* current() const {
if(!p) return 0;
return p->data;
}
// Pointer dereference operator:
T* operator->() const {
require(p != 0,
"PStack::iterator::operator->returns 0");
return current();
}
T* operator*() const { return current(); }
// bool conversion for conditional test:
operator bool() const { return bool(p); }
// Comparison to test for end:
bool operator==(const iterator&) const {
return p == 0;
}
bool operator!=(const iterator&) const {
return p != 0;
}
};
iterator begin() const {
return iterator(*this);
}
iterator end() const { return iterator(); }
};

template<class TStack<T>::~Stack() {
while(head)
delete pop();
}

template<class TT* Stack<T>::pop() {
if(head == 0) return 0;
T* result = head->data;
Link* oldHead = head;
head = head->next;
delete oldHead;
return result;
}

int main(){
}
Jul 30 '06 #1
Share this Question
Share on Google+
8 Replies


P: n/a
flamexx7 wrote:
Can anybody tell me what is wrong with declaration of pointer p ?
What does your compiler say about it? I tested your code with Comeau
online test, and it compiles fine.
template<class Tclass Stack {
struct Link {
T* data;
Link* next;
Link(T* dat, Link* nxt)
: data(dat), next(nxt) {}
}* head;
public:
Stack() : head(0) {}
~Stack();
void push(T* dat) {
head = new Link(dat, head);
}
T* peek() const {
return head ? head->data : 0;
}
T* pop();
// Nested iterator class:
class iterator; // Declaration required
friend class iterator; // Make it a friend
class iterator { // Now define it
Stack::Link* p;
I am guessing you're referring to the line above. What is the error
message you get (if any)?
public:
iterator(const Stack<T>& tl) : p(tl.head) {}
// Copy-constructor:
iterator(const iterator& tl) : p(tl.p) {}
// The end sentinel iterator:
iterator() : p(0) {}
// operator++ returns boolean indicating end:
bool operator++() {
if(p->next)
p = p->next;
else p = 0; // Indicates end of list
return bool(p);
}
bool operator++(int) { return operator++(); }
T* current() const {
if(!p) return 0;
return p->data;
}
// Pointer dereference operator:
T* operator->() const {
require(p != 0,
"PStack::iterator::operator->returns 0");
return current();
}
T* operator*() const { return current(); }
// bool conversion for conditional test:
operator bool() const { return bool(p); }
// Comparison to test for end:
bool operator==(const iterator&) const {
return p == 0;
}
bool operator!=(const iterator&) const {
return p != 0;
}
};
iterator begin() const {
return iterator(*this);
}
iterator end() const { return iterator(); }
};

template<class TStack<T>::~Stack() {
while(head)
delete pop();
}

template<class TT* Stack<T>::pop() {
if(head == 0) return 0;
T* result = head->data;
Link* oldHead = head;
head = head->next;
delete oldHead;
return result;
}

int main(){
You might want to try to use your template so that the compiler
actually attempts to instantiate the class.
}
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jul 30 '06 #2

P: n/a
In article <44***********************@news.sunsite.dk>,
"flamexx7" <none@nonewrote:
Can anybody tell me what is wrong with declaration of pointer p ?
Stack is a templated type and you don't use the template parameter when
declaring p. Also, Stack<T>::Link is a dependent type, so you have to
use the "typename" keyword. So declare it like this:

typename Stack<T>::Link* p;
Jul 30 '06 #3

P: n/a
Daniel T. wrote:
In article <44***********************@news.sunsite.dk>,
"flamexx7" <none@nonewrote:
>Can anybody tell me what is wrong with declaration of pointer p ?

Stack is a templated type and you don't use the template parameter
when declaring p. Also, Stack<T>::Link is a dependent type, so you
have to use the "typename" keyword. So declare it like this:

typename Stack<T>::Link* p;
Really? Comeau compiles the original program without a peep.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jul 30 '06 #4

P: n/a
I use Bloodshed 4.9.9.2 and after I applied solution provided by Daniel, my
code compiles fine.
"Victor Bazarov" <v.********@comAcast.netwrote in message
news:zI******************************@comcast.com. ..
Daniel T. wrote:
>In article <44***********************@news.sunsite.dk>,
"flamexx7" <none@nonewrote:
>>Can anybody tell me what is wrong with declaration of pointer p ?

Stack is a templated type and you don't use the template parameter
when declaring p. Also, Stack<T>::Link is a dependent type, so you
have to use the "typename" keyword. So declare it like this:

typename Stack<T>::Link* p;

Really? Comeau compiles the original program without a peep.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


Jul 30 '06 #5

P: n/a
Ok I found it. It's discuessed in section 14.6 of C++ Standard 2nd edtiion.
So after reading that, I figured out 3 simple ways :-

1. typename Stack<T>::Link* p;

2. We can skip template parametres.
typename Stack::Link* p;

3. We even need to provide name of class in which nested class is declared.
Link* p;
"flamexx7" <none@nonewrote in message
news:44***********************@news.sunsite.dk...
Can anybody tell me what is wrong with declaration of pointer p ?

template<class Tclass Stack {
struct Link {
T* data;
Link* next;
Link(T* dat, Link* nxt)
: data(dat), next(nxt) {}
}* head;
public:
Stack() : head(0) {}
~Stack();
void push(T* dat) {
head = new Link(dat, head);
}
T* peek() const {
return head ? head->data : 0;
}
T* pop();
// Nested iterator class:
class iterator; // Declaration required
friend class iterator; // Make it a friend
class iterator { // Now define it
Stack::Link* p;
public:
iterator(const Stack<T>& tl) : p(tl.head) {}
// Copy-constructor:
iterator(const iterator& tl) : p(tl.p) {}
// The end sentinel iterator:
iterator() : p(0) {}
// operator++ returns boolean indicating end:
bool operator++() {
if(p->next)
p = p->next;
else p = 0; // Indicates end of list
return bool(p);
}
bool operator++(int) { return operator++(); }
T* current() const {
if(!p) return 0;
return p->data;
}
// Pointer dereference operator:
T* operator->() const {
require(p != 0,
"PStack::iterator::operator->returns 0");
return current();
}
T* operator*() const { return current(); }
// bool conversion for conditional test:
operator bool() const { return bool(p); }
// Comparison to test for end:
bool operator==(const iterator&) const {
return p == 0;
}
bool operator!=(const iterator&) const {
return p != 0;
}
};
iterator begin() const {
return iterator(*this);
}
iterator end() const { return iterator(); }
};

template<class TStack<T>::~Stack() {
while(head)
delete pop();
}

template<class TT* Stack<T>::pop() {
if(head == 0) return 0;
T* result = head->data;
Link* oldHead = head;
head = head->next;
delete oldHead;
return result;
}

int main(){
}


Jul 30 '06 #6

P: n/a
In article <zI******************************@comcast.com>,
"Victor Bazarov" <v.********@comAcast.netwrote:
Daniel T. wrote:
In article <44***********************@news.sunsite.dk>,
"flamexx7" <none@nonewrote:
Can anybody tell me what is wrong with declaration of pointer p ?
Stack is a templated type and you don't use the template parameter
when declaring p. Also, Stack<T>::Link is a dependent type, so you
have to use the "typename" keyword. So declare it like this:

typename Stack<T>::Link* p;

Really? Comeau compiles the original program without a peep.
Gnu doesn't. I wonder what the standard says...
Jul 30 '06 #7

P: n/a
flamexx7 wrote:
I use Bloodshed 4.9.9.2 and after I applied solution provided by
Daniel, my code compiles fine.
Please don't top-post. See the FAQ entry at:
<http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.4>

Brian
Jul 30 '06 #8

P: n/a
Daniel T. wrote:
In article <zI******************************@comcast.com>,
"Victor Bazarov" <v.********@comAcast.netwrote:
>Daniel T. wrote:
>>In article <44***********************@news.sunsite.dk>,
"flamexx7" <none@nonewrote:

Can anybody tell me what is wrong with declaration of pointer p ?

Stack is a templated type and you don't use the template parameter
when declaring p. Also, Stack<T>::Link is a dependent type, so you
have to use the "typename" keyword. So declare it like this:

typename Stack<T>::Link* p;

Really? Comeau compiles the original program without a peep.

Gnu doesn't. I wonder what the standard says...
It's a Gnu's problem. In the original post, 'iterator' is a member,
that means 'Stack' in it refers to the outer template Stack. That
means that Stack::Link is _not_ a dependent name since 'iterator' is
not translated _independently_ of 'Stack'.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jul 30 '06 #9

This discussion thread is closed

Replies have been disabled for this discussion.