views:

402

answers:

2

I'm trying to return an iterator for a vector in a templated class (I'm not sure if that makes a difference, but I've read that may, so I thought I'd mention it). The problem is that I get an error about C++ not supporting default-int when I try this. I've looked online and from what I can see in forums and explanaions, I don't think I'm that far off, it just won't compile.

template<class T>
class Table
{
public:
  ...

  vector<shared_ptr<vector<T>>>::iterator GetRowIterator();
  //vector<shared_ptr<vector<CellValueType> > >::const_iterator GetRowIterator();

  ...
protected:

  vector<shared_ptr<vector<CellValueType> > > data;  //outside vector is rows, inside vector is columns

  ...
};

vector<shared_ptr<vector<T> > >::const_iterator Table<T>::GetRowIterator()
{
  return data.begin();
}

The errors that I get are:

error C2146: syntax error : missing ';' before identifier 'GetRowIterator'

error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

Edit:
Changed the end angle brackets so they are not as close together - same error.

Any thoughts as to why this is occurring?
As always, thanks for advice/help in advance!

+3  A: 

This part here:

vector<shared_ptr<vector<T>>>

It is a problem with the C++ syntax you can not put >> together like that.

vector<shared_ptr<vector<T> > >

This is a problem that is being addressed by the new standard.

Because the lexer is the first stage of the compiler it sees the >>> as a shift left operator followed by >. Thus you are getting syntax errors in your code. To supress this problem you just need to add white space between the > when closing templates.

Martin York
In recent (post-VS2003) MSVC that is not a problem, it recognizes the closing angle brackets correctly.
Fabio Ceconello
Wasn't the root of the problem, but a good rule of thumb. Thanks for the advice! +1
Fry
+3  A: 

Also remember to use typename when declaring the template-dependent return type:

typename vector< shared_ptr< vector< T > > >::iterator GetRowIterator();

and the method definition

typename vector< shared_ptr< vector< T > > >::const_iterator Table<T>::GetRowIterator()
{
  return data.begin();
}

Notice also that when defining a template class method outside the class definition, you have to use the template keyword:

template <class T> typename vector< shared_ptr< vector< T > > >::const_iterator Table<T>::GetRowIterator()
    {
      return data.begin();
    }

So that the compiler can know what the T is about.

Fabio Ceconello
Worked like a charm! Thanks. This is the first time I've used iterators in a template class, so this was a very useful learning experience :)
Fry