`token" I have the following code in a project that I am doing for a class. I...">

Problem with templates in C ++: "Expected primary expression before`> `token"

I have the following code in a project that I am doing for a class. I had problems with the expression for printing for several hours, and I could not find what I needed on the Internet.

Here is my definition of a template class:

template <class T> class oset { template <class U> class node { ..... }; ..... public: template <class U> class iter { node<U> *pos; // node _before_ the one with this->operator* // constructor is private: iter(node<U>* n) : pos(n) { } friend class oset<U>; .... }; private: iter<T> start; // initialized in the constructors below iter<T> finish; // initialized in the constructors below public: iter<T> begin() { return start; } iter<T> end() { return finish; } .... }; 

Then the problem I have is in print:

 template <class S> void print(oset<S>& OS) { for (oset<S>::iter<S> i = OS.begin(); i != OS.end(); ++i) { // ^-- error is on previous line cout << *i << " "; } cout << endl; } 

When I try to compile with g ++, I get the following error message:

oset.cc:276: error: expected primary expression before '> token

oset.cc:276: error: 'i was not declared in this area

The problem is in the comments. Problems with the '>' marker are immediately before the first i . For some reason, <S> doesn't like it. If I get rid of <S> , he will tell me what he expects ';' before i

I honestly have no idea what causes the problem. I am very upset and any help would be greatly appreciated. Thanks!

+6
source share
1 answer
 for (oset<S>::iter<S> i = OS.begin(); i != OS.end(); ++i) { //error this line 

Here you should use typename and template :

 for (typename oset<S>::template iter<S> i = OS.begin(); i != OS.end(); ++i) 

Please note that none of the following will work:

 oset<S>::iter<S> i //error typename oset<S>::iter<S> i //error oset<S>::template iter<S> i //error 

Your situation is that you should use both keywords: typename , as well as template :

 typename oset<S>::template iter<S> i //ok 

Why you need both keywords here is explained by @Johannes in this section:


Some tips and improvements

  • Make the iterator class not a template. Use T wherever you use U in your definition.
  • Also rename the class from iter to iterator . Make it look like a standard container / iterator so that you can use it in the agorites defined in <algorithm> .

That is, your class should look like this:

 class iterator { node<T> *pos; iterator(node<T>* n) : pos(n) { } friend class oset<T>; }; 

Then in a for loop you will need a typename like:

 typename oset<S>::iterator i //ok 
+9
source

Source: https://habr.com/ru/post/903504/


All Articles