Menu

friend, template, nested class

2002-11-01
2012-09-26
  • Nobody/Anonymous

    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

     
    • Nobody/Anonymous

      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...
      };

       
      • Nobody/Anonymous

        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.

         
        • Nobody/Anonymous

          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

           
    • Nobody/Anonymous

      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

       
    • Nobody/Anonymous

      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.

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.