1

I can't figure out how to use type aliasing for nested classes. Below is a class declaration for a linked list. I originally implemented the linkedlist class with the node and iterator classes alongside linkedlist, and am now trying to nest them inside of linkedlist. To make the class easier to read, I'd rather just use iterator instead of linkedlist::iterator everywhere, so I want to type alias it as just iterator. Below is one of my attempts, no matter what I change I end up with one error or another. This one doesn't work because the line

class linkedlist::iterator;

causes the error (g++ -std=c++11) 'iterator' in 'class linkedlist' does not name a type.

class linkedlist;
class linkedlist::iterator;
class linkedlist::node;
using iterator = linkedlist::iterator;
using node = linkedlist::node;


class linkedlist
{
public:

  linkedlist();  
  iterator begin(); 
  iterator end();
  iterator insert(iterator pos, long data);
  void print();

  node* root;
  node* final;



private:
  class iterator
  {
  public:


    const linkedlist* list;
    node* ref;

    iterator();
    iterator(node& ref, const linkedlist& list);

    long& operator*();
    long* operator->();
    iterator& operator++(); 
    iterator& operator--();
    bool operator==(iterator rhs);
    bool operator!=(iterator rhs);

  };


private:  
  class node
  {
  public:

    long& operator*();

    long data;
    node* ptr_f;
    node* ptr_b;
  };

};
roro
  • 931
  • 5
  • 21
  • 1
    Rather than declaring the alias *outside* the class (which then means that unnamespaced `iterator` is available to all code including this header), wouldn't it make more sense to predeclare `iterator` *inside* the class? Also, I don't think it makes sense for `iterator` to be private if there are public member functions that take and/or return instances of it. Those signatures won't be usable outside the class, will they? – ruakh Dec 11 '16 at 02:58
  • I'll try that. As for the public/private, I haven't thought out the interface yet, you're probably right about that. – roro Dec 11 '16 at 03:00
  • You should be able to use auto keyword for most local declarations... Also, either you have an nested iterator with nested name or you move out the nested class to the parent level if you want unqualified name. Or you do local alias when you need them if you don't want to pollute global namespace but would like shorter name in some source files (or inside some functions/classes). – Phil1970 Dec 11 '16 at 03:18
  • 1
    You cannot do an alias before the parent class is defined but you should be able to do it after the class definition. However, you don't want to do it in the header as it would pollute the namespace and if you do so, then why nested the class to begin with? In C++, I don't think it give any advantage to be nested. – Phil1970 Dec 11 '16 at 03:23

1 Answers1

2
class linkedlist;

This is called a "forward declaration".

Only top level classes can be forwardly-declared. Nested classes cannot be forwardly-declared outside of the class.

Now once you're in the process defining a class, you can forwardly-declare nested classes within the scope of the class:

class linkedlist {

    class iterator;

    // Stuff that uses the forwardly-declared iterator class

    class iterator {

        // And the definition of the iterator class
    };
};

That's how forward declaration works.

In your example, just move both "using" aliases after the definition of the linkedlist class (after making the nested classes public), that's all.

I agree, it would be nice of nested forward declarations were possible, outside of their scope, but they're not. Such is life.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • This clears some things up, but I guess what I want to do can't really be done. When writing the implementations, I still have to write linkedlist::iterator, however including a type alias for this will add the alias to the entire namespace, so that in main iterator will be a valid type. – roro Dec 11 '16 at 03:14
  • C++ isn't perfect. At least not yet. – Sam Varshavchik Dec 11 '16 at 03:15