Templates, nested classes, and “expected constructor, destructor, or conversion before '&' token”

StackOverflow https://stackoverflow.com/questions/1725147

  •  19-09-2019
  •  | 
  •  

Question

While working with some templates and writing myself a basic container class with iterators, I found myself needing to move the body of member functions from a template class into a separate file to conform to style guidelines. However, I've run into an interesting compile error:

runtimearray.cpp:17: error: expected constructor, destructor, or type conversion before '&' token runtimearray.cpp:24: error: expected constructor, destructor, or type conversion before '&' token runtimearray.cpp:32: error: expected constructor, destructor, or type conversion before '&' token runtimearray.cpp:39: error: expected constructor, destructor, or type conversion before '&' token runtimearray.cpp:85: error: expected constructor, destructor, or type conversion before 'RuntimeArray' runtimearray.cpp:91: error: expected constructor, destructor, or type conversion before 'RuntimeArray'

runtimearray.h:

#ifndef RUNTIMEARRAY_H_
#define RUNTIMEARRAY_H_

template<typename T>
class RuntimeArray
{
 public:
  class Iterator
  {
    friend class RuntimeArray;
   public:
    Iterator(const Iterator& other);

    T& operator*();
    Iterator& operator++();
    Iterator& operator++(int);
    Iterator& operator--();
    Iterator& operator--(int);
    bool operator==(Iterator other);
    bool operator!=(Iterator other);

   private:
    Iterator(T* location);

    T* value_;
  };

  RuntimeArray(int size);
  ~RuntimeArray();

  T& operator[](int index);

  Iterator Begin();
  Iterator End();

 private:
  int size_;
  T* contents_;
};

#endif  // RUNTIMEARRAY_H_

runtimearray.cpp:

#include "runtimearray.h"

template<typename T>
RuntimeArray<T>::Iterator::Iterator(const Iterator& other)
    : value_(other.value_)
{
}

template<typename T>
T& RuntimeArray<T>::Iterator::operator*()
{
  return *value_;
}

template<typename T>
RuntimeArray<T>::Iterator& RuntimeArray<T>::Iterator::operator++()
{
  ++value_;
  return *this;
}

template<typename T>
RuntimeArray<T>::Iterator& RuntimeArray<T>::Iterator::operator++(int)
{
  Iterator old = *this;
  ++value_;
  return old;
}

template<typename T>
RuntimeArray<T>::Iterator& RuntimeArray<T>::Iterator::operator--()
{
  --value_;
  return *this;
}

template<typename T>
RuntimeArray<T>::Iterator& RuntimeArray<T>::Iterator::operator--(int)
{
  Iterator old = *this;
  --value_;
  return old;
}

template<typename T>
bool RuntimeArray<T>::Iterator::operator==(Iterator other)
{
  return value_ == other.value_;
}

template<typename T>
bool RuntimeArray<T>::Iterator::operator!=(Iterator other)
{
  return value_ != other.value_;
}

template<typename T>
RuntimeArray<T>::Iterator::Iterator(T* location)
    : value_(location)
{
}

template<typename T>
RuntimeArray<T>::RuntimeArray(int size)
    : size_(size),
      contents_(new T[size])
{
}

template<typename T>
RuntimeArray<T>::~RuntimeArray()
{
  if(contents_)
    delete[] contents_;
}

template<typename T>
T& RuntimeArray<T>::operator[](int index)
{
  return contents_[index];
}

template<typename T>
RuntimeArray<T>::Iterator RuntimeArray<T>::Begin()
{
  return Iterator(contents_);
}

template<typename T>
RuntimeArray<T>::Iterator RuntimeArray<T>::End()
{
  return Iterator(contents_ + size_);
}

How can I make these errors go away? The files make sense to me, but alas, it's the compiler's say that matters.

Was it helpful?

Solution

I think that you are missing the typename keyword.

e.g.

template<typename T>
RuntimeArray<T>::Iterator& RuntimeArray<T>::Iterator::operator++()

should be

template<typename T>
typename RuntimeArray<T>::Iterator& RuntimeArray<T>::Iterator::operator++()

'Nested' types which are dependent on a template parameter need the typename keyword to tell the compiler that they should be types where this otherwise would be ambiguous.

OTHER TIPS

That is one heck of a funny style guideline. In general, definitions of template functions have to be in the header file. This came by just a few hours ago: Splitting templated C++ classes into .hpp/.cpp files--is it possible?

This will not work the way you want it to. All your function declarations and definitions must appear in the .h file in which you defined RuntimeArray. The error you're seeing may be something else, perhaps a typename thing, but even if you can make RunTimeArray.cpp compile in isolation no one will be able to use it.

If you really must have the definitions in a separate file, #include it at the end of runtimearray.h

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top