3

いくつかのテンプレートを操作し、反復子を使用して基本的なコンテナー クラスを作成しているときに、スタイル ガイドラインに準拠するために、メンバー関数の本体をテンプレート クラスから別のファイルに移動する必要があることに気付きました。ただし、興味深いコンパイル エラーが発生しました。

runtimearray.cpp:17: エラー: '&' トークンの前にコンストラクタ、デストラクタ、または型変換が必要です runtimearray.cpp:24: エラー: '&' トークンの前にコンストラクタ、デストラクタ、または型変換が必要です runtimearray.cpp:32: エラー: '&' トークンの前にコンストラクタ、デストラクタ、または型変換が必要です runtimearray.cpp:39: エラー: '&' トークンの前にコンストラクタ、デストラクタ、または型変換が必要です runtimearray.cpp:85: エラー: コンストラクタ、デストラクタ、または型変換が必要です'RuntimeArray' の前に runtimearray.cpp:91: エラー: '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_

ランタイム配列.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_);
}

これらのエラーをなくすにはどうすればよいですか? ファイルは私には理にかなっていますが、残念ながら、重要なのはコンパイラの発言です。

4

3 に答える 3

12

typenameキーワードが抜けていると思います。

例えば

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

する必要があります

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

テンプレート パラメーターに依存する「ネストされた」型には、typenameキーワードが必要であり、コンパイラーに型であるべきであることを伝える必要があります。

于 2009-11-12T20:34:35.943 に答える
2

これは面白いスタイル ガイドラインの 1 つです。一般に、テンプレート関数の定義はヘッダー ファイルにある必要がありますテンプレート化された C++ クラスを.hpp /.cpp ファイルに分割することは可能ですか?

于 2009-11-12T20:33:26.997 に答える
2

これでは思い通りにはいきません。関数の宣言と定義はすべて、RuntimeArray を定義した .h ファイルに含まれている必要があります。表示されているエラーは別のもの、おそらく型名の問題である可能性がありますが、RunTimeArray.cpp を分離してコンパイルできたとしても、誰もそれを使用できません。

定義を別のファイルに入れる必要がある場合は#include、runtimearray.h の最後に置きます。

于 2009-11-12T20:37:30.807 に答える