Brian
Brian

Reputation: 23

Instantiating Template Object within a template

I'm taking a C++ class, and am having trouble figuring out one of the homework assignments. We are given the following class (which I've added to my .h file, and we were told not to modify), and told to implement the iterator class.

template <typename T>
class IntegerRange
{
public:
  class iterator;

  IntegerRange(T low, T high) : low_(low), high_(high)
  {
    assert(low <= high);
  }

  const iterator begin() const {return iterator(low_); }
  const iterator end() const {return iterator(high_); }

private:
      const T low_, high_;
};

We were given the following of a way it would be used:

IntegerRange<int> r1(-2, 3);
copy(r1.begin(), r1.end(), ostream_iterator<int>(cout, " "));  //-2 -1 0 1 2

IntegerRange<unsigned> r2(0, 6);
copy(r2.begin(), r2.end(), ostream_iterator<unsigned>(cout, " ")); //0 1 2 3 4 5

For starters, I was just trying to get the code to compile so I could play around with it and figure it out, but I'm having a hard time with even that. I added the following code to the same .h file, but am getting the error "Implicit instantiation of undefined member 'IntegerRange::iterator'"

template <typename T>
class iterator
{
public:
  iterator(T data) : data_(data) {}

private:
  T data_;
};

I'm not looking to have anyone tell me how to do the whole assignment - just wondering how I can even get it to compile? Thanks! Full main.cpp & IntegerRange.h files below:

//main.cpp
#include <iostream>
#include "IntegerRange.h"
#include <algorithm>
 using std::copy;
 using std::cout;
 using std::ostream_iterator;

 int main()
{
  IntegerRange<int> r1(-2, 3);
  copy(r1.begin(), r1.end(), ostream_iterator<int>(cout, " "));  //-2 -1 0 1 2

  IntegerRange<unsigned> r2(0, 6);
  copy(r2.begin(), r2.end(), ostream_iterator<unsigned>(cout, " ")); //0 1 2 3 4 5
  return 0;
}

//IntegerRange
#ifndef Homework7_IntegerRange_h
#define Homework7_IntegerRange_h

#include <cassert>

template <typename T>
class iterator
{
public:
  iterator(T data) : data_(data) {}

private:
  T data_;
};


template <typename T>
class IntegerRange
{
public:
  class iterator;

  IntegerRange(T low, T high) : low_(low), high_(high)
  {
    assert(low <= high);
  }

  const iterator begin() const {return iterator(low_); }
  const iterator end() const {return iterator(high_); }

private:
  const T low_, high_;
};

#endif

Upvotes: 0

Views: 169

Answers (3)

vsoftco
vsoftco

Reputation: 56577

Hint: (you still need to implement ++ operators etc.)

#include <iostream>
#include <algorithm>
#include <iterator>

using namespace std;

template <typename T>
class IntegerRange
{
public:
    class iterator
    {
    public:
        iterator(T data) : data_(data) {}
        const T& operator*(){return data_;};
    private:
        T data_;
    };

    IntegerRange(T low, T high) : low_(low), high_(high)
    {
        assert(low <= high);
    }

    const iterator begin() const {return iterator(low_); }
    const iterator end() const {return iterator(high_); }

private:
    const T low_, high_;
};


int main()
{
    IntegerRange<int> r1(-2, 3);
    auto it=r1.begin();
    cout << *it << endl;
}

Upvotes: 0

Philipp Cla&#223;en
Philipp Cla&#223;en

Reputation: 44009

IntegerRange defines an inner class iterator.

template <typename T>
class IntegerRange
{
public:
  class iterator; // forward declaration
  ...

I think, the problem is that you are not implementing an inner class of IntegerRange but a standalone class:

template <typename T>
class iterator
{
public:
  iterator(T data) : data_(data) {}
  ...

So the compiler thinks it is a complete unrelated class. Try to move your implementation of iterator inside the IntegerRange class (for example, replacing the forward declaration by your implementation).

As you said, you must not update the IntegerRange class, you have to qualify the iterator class using this idea:

class MyOuterClass::MyInnerClass
{
  // ...
};

Upvotes: 2

ubi
ubi

Reputation: 4399

If you wanted to forward declare class iterator declare it outside of class IntegerRange. Or did you want to declare it as a friend class? e.g.,

template <typename T>
class IntegerRange
{
public:
  friend class iterator;

  // ...
};

Upvotes: 0

Related Questions