jimifiki
jimifiki

Reputation: 5544

template constructor and typedef iterator

I want to define a constructor working with any constructor having begin, end, operator++. In other words I want to get this behavior (commented, working code):

/*Polyn(std::vector<double> &a) : CalcDerivative(0) , CalcIntegral(0) {
    for(std::vector<double>::iterator i = a.begin();i < a.end();++i)
      params.push_back(*i);
    }*/

with other iterators. (for instance lists too).

template <typename T>
  Polyn(const T &a) : CalcDerivative(0) , CalcIntegral(0) {
  typename std::vector<T>::iterator iter;
  for(iter i = a.begin();i < a.end();++i) //LINEA 18!!
    params.push_back(*i);
  }

What I get is this compilation error:

polyn.h: In constructor ‘Polyn::Polyn(const T&)’:
polyn.h:18: error: expected ‘;’ before ‘i’

why? How to fix my code?

Upvotes: 1

Views: 1260

Answers (2)

Christian Rau
Christian Rau

Reputation: 45948

In addition to Nawaz's answer, if you want to support any container type supporting begin, end and a forward iterator, you may want to use:

template <typename C>
Polyn(const C &a) 
  : params(a.begin(), a.end()), CalcDerivative(0) , CalcIntegral(0) 
{
}

This way it also works for std::lists and std::maps and whatever. Or, when having C++11 support, you should actually use the even more general std::begin(a) and std::end(a), so it will even work for plain arrays or anything else specializing std::begin and std::end.

Another option, which is a bit more STL-like, would be to directly use iterators as arguments, but then you have to do the begin/end manually in the client code (when calling the constructor):

template <typename InputIterator>
Polyn(const InputIterator &b, const InputIterator &e) 
  : params(b, e), CalcDerivative(0) , CalcIntegral(0) 
{
}

Upvotes: 1

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361612

First of all, the parameter type of the function should be std::vector<T> const & rather than T const &. And then you should use const_iterator:

typename std::vector<T>::const_iterator iter;

Because vector a is a const object.

Even better if you implement the constructor as:

template <typename T>
Polyn(const std::vector<T> &a) 
  : params(a.begin(), a.end()), CalcDerivative(0) , CalcIntegral(0) 
{
}

That is, initialize params in the member-initialization-list itself.

Upvotes: 2

Related Questions