Modèles, classes imbriquées, et « constructeur attendu, destructor ou conversion avant « et » jeton »

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

  •  19-09-2019
  •  | 
  •  

Question

Tout en travaillant avec certains modèles et moi-même écrire une classe conteneur de base avec itérateurs, je me suis retrouvé avoir besoin de déplacer le corps des fonctions membres d'une classe de modèle dans un fichier séparé pour se conformer aux directives de style. Cependant, j'ai rencontré une erreur de compilation intéressante:

  

runtimearray.cpp: 17: erreur: attendu   constructeur, destructor, ou du type   conversion avant « et » jeton   runtimearray.cpp: 24: erreur: prévu   constructeur, destructor, ou du type   conversion avant « et » jeton   runtimearray.cpp: 32: erreur: attendu   constructeur, destructor, ou du type   conversion avant « et » jeton   runtimearray.cpp: 39: erreur: attendu   constructeur, destructor, ou du type   conversion avant « et » jeton   runtimearray.cpp: 85: Erreur: attendu   constructeur, destructor, ou du type   conversion avant 'RuntimeArray'   runtimearray.cpp: 91: erreur: attendu   constructeur, destructor, ou du type   conversion avant '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_);
}

Comment puis-je faire ces erreurs disparaissent? Les fichiers me font sens, mais hélas, ce sont les années compilateur dire que les questions.

Était-ce utile?

La solution

Je pense que vous manque le mot-clé typename.

par exemple.

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

doit être

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

« emboîtés » types qui dépendent d'un paramètre de modèle ont besoin du mot-clé typename pour indiquer au compilateur qu'ils devraient être types où cela serait autrement ambigu.

Autres conseils

C'est un diable d'une ligne directrice de style drôle. En général, les définitions des fonctions de modèle Vous pour être dans le fichier d'en-tête. Cela est venu il y a quelques heures: Fractionnement des classes C ++ basé sur un modèle en fichiers .hpp / Cpp - est-il possible

Cela ne fonctionne pas comme vous le souhaitez. Toutes vos déclarations de fonction et définitions doivent apparaître dans le fichier .h dans lequel vous avez défini RuntimeArray. L'erreur que vous voyez peut-être quelque chose d'autre, peut-être une chose typename, mais même si vous pouvez faire RunTimeArray.cpp compiler isolément ne pourra l'utiliser.

Si vous devez vraiment avoir les définitions dans un fichier séparé, #include à la fin de runtimearray.h

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top