Good day. There is a template class:

template<class T> class List { struct Node { T elem; Node* next; Node* prev; Node(); }; int count; Node* head; Node *tail; public: // ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ }; 

Also, I have a nested regular iterator class:

 class Iterator { Node* element; public: // ΠšΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ‚ΠΎΡ€Ρ‹ ΠΈ ΠΏΠ΅Ρ€Π΅Π³Ρ€ΡƒΠ·ΠΊΠΈ Iterator(const Iterator&); // инициализация ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠΌ Iterator(Node*); // инициализация ΡƒΠ·Π»ΠΎΠΌ Iterator& operator=(Node* node) // присвоСниС ΡƒΠ·Π»Π° { if (*this == &node) return *this; this->elem = node; return *this; } // ΠœΠ°Π½ΠΈΠΏΡƒΠ»ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ bool hasNext(); // Π΅ΡΡ‚ΡŒ Π»ΠΈ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ bool hasPrev(); // Π΅ΡΡ‚ΡŒ Π»ΠΈ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΉ T next(); // ΠΊ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌΡƒ T prev(); // ΠΊ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΌΡƒ }; 

Simple class. How to bring the implementation of the overloaded operator = out of the Iterator class beyond its limits, and the limits of the List class? Tried a lot of things, the errors are rather strange: Error C2143 syntax error: the absence of a ";" before "{"

Thanks in advance!

    2 answers 2

    In the classic syntax

     template <class T> typename List<T>::Iterator &List<T>::Iterator::operator =(Node *node) { ... } 

    Note that the qualified name List<T>::Iterator (and, as a result, the keyword typename ) is required only in the return value type. In the parameter list, you can use "short" type names, i.e. Node .

    In C ++ 11, you can also write it this way (without succumbing to the temptation to use C ++ 14 deduction of the return type)

     template <class T> auto List<T>::Iterator::operator =(Node* node) -> Iterator & { ... } 

    In this syntax, there is no need to use a qualified name (and typename ) in the return type.

    • Thank you very much for the tip! The only thing I would like to understand is the following: Why do we write typename before the construction? I, in fact, did just that ... except for the key typename - Range
    • When you specify the nested type of the template class and at the same time not all parameters are specified, you need to add a typename . In this case, to reference the List<T>::Iterator need the prefix typename . But for the reference to List<int>::Iterator no longer need a typename , since All parameters of the template are "fixed". - AnT
    • Thank you, everything became clear. - Range

    If you do not focus on the implementation of this operator, then it can be defined as follows

     template <class T> typename List<T>::Iterator & List<T>::Iterator::operator =( typename List<T>::Node *node ) { if ( this->element != node ) this->element = node; return *this; } 

    Or more simply

     template <class T> typename List<T>::Iterator & List<T>::Iterator::operator =( Node *node ) { if ( this->element != node ) this->element = node; return *this; } 
    • Indeed, you can implement the operator easier, just somehow did not think, made a standard entry. Thank you. - Range