模板,嵌套类和“预期的构造函数,析构函数或转换'之前'&'令牌”

时间:2009-11-12 20:29:35

标签: c++ templates nested-class

在使用一些模板并使用迭代器编写自己的基本容器类时,我发现自己需要将成员函数体从模板类移动到单独的文件中以符合样式指南。但是,我遇到了一个有趣的编译错误:

  

runtimearray.cpp:17:错误:预期   构造函数,析构函数或类型   '&'之前的转换代币   runtimearray.cpp:24:错误:预期   构造函数,析构函数或类型   '&'之前的转换代币   runtimearray.cpp:32:错误:预期   构造函数,析构函数或类型   '&'之前的转换代币   runtimearray.cpp:39:错误:预期   构造函数,析构函数或类型   '&'之前的转换代币   runtimearray.cpp:85:错误:预期   构造函数,析构函数或类型   'RuntimeArray'之前的转换   runtimearray.cpp:91:错误:预期   构造函数,析构函数或类型   '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_);
}

如何让这些错误消失?这些文件对我来说很有意义,但唉,编译器认为这很重要。

3 个答案:

答案 0 :(得分:12)

我认为您错过了typename关键字。

e.g。

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

应该是

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

'依赖于模板参数的'嵌套'类型需要typename关键字告诉编译器它们应该是类型,否则这将是不明确的。

答案 1 :(得分:2)

这是一个有趣的风格指南。通常,模板函数的定义位于头文件中。这是在几个小时前发生的:Splitting templated C++ classes into .hpp/.cpp files--is it possible?

答案 2 :(得分:2)

这不会按照你想要的方式工作。所有函数声明和定义必须出现在您定义RuntimeArray的.h文件中。你看到的错误可能是其他的东西,也许是一个typename的东西,但即使你可以单独编译RunTimeArray.cpp,也没有人能够使用它。

如果你真的必须在一个单独的文件中定义,#include它在runtimearray.h的末尾