The problem is I want to template alphatree, but the compiler takes a big exception to the line in class Tnode that declares alphatree::iterator to be a friend. Clearly it is no longer just alphatree but alphatree<T>, however the line: friend class alphatree::iterator; does work in alphatree::iterator.
What the hell should this line - indicated by /'s - be?
i'm not quite sure if this is a proper answer, but after fooling around with templates a little bit it seems that the compiler won't accept internal classes as friends. Go figure. I guess you can work around the problem by making iterator a separate template from alphatree. Something like this:
template<class T> class iterator; // forward declaration
// other stuff...
template<class T> class alphatree
{
public:
typedef iterator<T> iter;
// other members of alphatree, but no iterator here
};
template<class T> class iterator
{
friend class alphatree<T>;
// other members of iterator
};
class Tnode
{
template<class T> friend class alphatree;
template<class T> friend class iterator;
// rest of Tnode...
};
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Wait, I take that back... the compiler does take internal classes as friends if they're not templates, so the problem must have something to do with templates and internal classes refusing to work together. I'm baffled.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
You may be right: I'm buggered if I can get it to work.
I was hoping to make it kook like the STL, but if I move iterator outside alphatree then it will be declared as iterator - rather than alphatree<int>::iterator.
What we really need is for a friendly STL author to come along: the STL must do something similar to what I want for node-based containers like lists.
Thanks for replying anyway
Derek
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Notice that in my above solution, alphatree<int>::iter is typedef'd to refer to iterator<int>, so you get the same functionality, you just can't declare all the possible alphatree<int>'s as friends with a template (actually, I can't imagine why you'd want to do that anyway...). I don't know if STL uses friends like you do at all.
Also, i noticed that if the nested class is also a template, it works. Boggles the mind.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The problem is I want to template alphatree, but the compiler takes a big exception to the line in class Tnode that declares alphatree::iterator to be a friend. Clearly it is no longer just alphatree but alphatree<T>, however the line: friend class alphatree::iterator; does work in alphatree::iterator.
What the hell should this line - indicated by /'s - be?
Thanks
Derek
#ifndef INCLUDEGUARD_ALPHATREE_H
#define INCLUDEGUARD_ALPHATREE_H
#include <string>
template<class T>class alphatree;
class iterator;
class Tnode;
template<class T>class alphatree
{
public:
class iterator;
alphatree();
iterator begin();
void clear();
bool empty();
iterator end();
iterator erase(string&);
iterator erase(const char*);
iterator erase(alphatree::iterator);
iterator get(string&);
iterator get(const char*);
string get(alphatree::iterator);
void merge(alphatree&);
alphatree::iterator put (string&);
alphatree::iterator put(const char*);
int size();
private:
Tnode* CreateNode(string, int, Tnode*);
Tnode* firstnode;
Tnode* lastnode;
Tnode* root;
Tnode* endroot;
int nodecount;
public:
class iterator
{
template<class T> friend class alphatree;
public:
iterator();
iterator(Tnode*);
friend ostream& operator<< (ostream& os,
alphatree::iterator i);
void operator=(iterator);
bool operator==(iterator);
bool operator!=(iterator);
iterator operator++();
iterator operator++(int);
iterator operator--();
iterator operator--(int);
Tnode* operator->();
private:
Tnode* it;
};
friend class alphatree::iterator;
};
class Tnode
{
template<class T> friend class alphatree;
///////////problem below here/////
friend class alphatree::iterator;
//////////////////////////////////
public:
string word;
int count;
private:
int flag;
Tnode* parent;
Tnode* branches[26];
};
#endif
i'm not quite sure if this is a proper answer, but after fooling around with templates a little bit it seems that the compiler won't accept internal classes as friends. Go figure. I guess you can work around the problem by making iterator a separate template from alphatree. Something like this:
template<class T> class iterator; // forward declaration
// other stuff...
template<class T> class alphatree
{
public:
typedef iterator<T> iter;
// other members of alphatree, but no iterator here
};
template<class T> class iterator
{
friend class alphatree<T>;
// other members of iterator
};
class Tnode
{
template<class T> friend class alphatree;
template<class T> friend class iterator;
// rest of Tnode...
};
Wait, I take that back... the compiler does take internal classes as friends if they're not templates, so the problem must have something to do with templates and internal classes refusing to work together. I'm baffled.
If anyone is interested I now have it templated.
I moved Tnode into alphatree and templated it, now no problem with the friend relationships I wanted.
Derek
You may be right: I'm buggered if I can get it to work.
I was hoping to make it kook like the STL, but if I move iterator outside alphatree then it will be declared as iterator - rather than alphatree<int>::iterator.
What we really need is for a friendly STL author to come along: the STL must do something similar to what I want for node-based containers like lists.
Thanks for replying anyway
Derek
Notice that in my above solution, alphatree<int>::iter is typedef'd to refer to iterator<int>, so you get the same functionality, you just can't declare all the possible alphatree<int>'s as friends with a template (actually, I can't imagine why you'd want to do that anyway...). I don't know if STL uses friends like you do at all.
Also, i noticed that if the nested class is also a template, it works. Boggles the mind.