使用模板时,如何修复以下编译器错误以实现程序的预期行为?

When using templates, how do I fix the following compiler error to achieve the desired behavior of my program?

我正在练习 Visual Studio 2013 中一本写得不太好的 C++ 书籍中的模板,我分别收到以下编译器错误,"error C4430: missing type specifier - int assumed. Note: C++ does not support default-int""error C2143: syntax error : missing ',' before '<'".

两者都让我参考第 10 行,即...

std::ostream& operator<< (std::ostream&, const Array<T>&);

我的代码的期望行为 是显示使用模板创建和销毁临时 Animal 对象。

我目前尝试的故障排除步骤包括用int[=54=替换std::iostream& ] 在我的 return 类型和第 10 行的第一个参数类型中。这样做之后,错误消息保持不变。这似乎表明问题可能出在第二个参数类型上。然后,我在第 10 行的重载运算符函数 (operator<<) 的第二个参数中添加了关键字 typename,错误仍然存​​在。

第 10 行可以在下面的头文件中找到。

//Array.h

#ifndef ARRAY_H
#define ARRAY_H

#include <iostream>
#include "Animal.h"

const int DefaultSize = 3;

template <typename T>
std::ostream& operator<< (std::ostream&, const Array<T>&);

template <typename T> // declare the template and the paramenter
class Array               // the class being parameterized
{
public:
  Array(int itsSize = DefaultSize);
  Array(const Array &rhs);
  ~Array() { delete[] pType; }

  // operators
  Array& operator=(const Array&);
  T& operator[](int offSet) { return pType[offSet]; }
  const T& operator[](int offSet) const { return pType[offSet]; }

  // accessors
  int GetSize() const { return itsSize; }

  // friend function
  friend std::ostream& operator<< (std::ostream&, const Array<T>&);

private:
  T *pType;
  int itsSize;
};

template <typename T>
Array<T>::Array(int size = DefaultSize) :itsSize(size)
{
  pType = new T[size];
  for (int i = 0; i < size; i++)
      pType[i] = static_cast<T>(0);
}

Array<Animal>::Array(int AnimalArraySize) :itsSize(AnimalArraySize)
{
  pType = new Animal[AnimalArraySize];
}

template <typename T>
Array<T>::Array(const Array &rhs)
{
  itsSize = rhs.GetSzie();
  pType = new T[itsSize];
  for (int i = 0; i < itsSize; i++)
      pType[i] = rhs[i];
}

template <typename T>
Array<T>& Array<T>::operator=(const Array &rhs)
{
  if (this == &rhs)
      return *this;
  delete[] pType;
  itsSize = rhs.GetSize();
  pType = new T[itsSize];
  for (int i = 0; i < itsSize; i++)
      pType[i] = rhs[i];
  return *this;
}

template <typename T>
std::ostream& operator<< (std::ostream& output, const Array<T> &theArray)
{
  for (int i = 0; i < theArray.GetSize(); i++)
      output << "[" << i << "]" << theArray[i] << std::endl;
  return output;
}

#endif

这是我书中的其余代码,供您参考。

//Animal.h

#ifndef ANIMAL_H
#define ANIMAL_H

#include <iostream>

class Animal
{
public:
  // constructors
  Animal();
  Animal(int);
  ~Animal();

  // accessors
  int GetWeight() const { return itsWeight; }
  void SetWeight(int theWeight) { itsWeight = theWeight; }

  // friend operators
  friend std::ostream& operator<<(std::ostream&, const Animal&);

private:
  int itsWeight;
};

#endif

//Animal.cpp

#include "Animal.h"
#include <iostream>

Animal::Animal() :itsWeight(0)
{
  std::cout << "animal() ";
}

Animal::Animal(int weight) : itsWeight(weight)
{
  std::cout << "animal(int) ";
}

Animal::~Animal()
{
  std::cout << "Destroyed an animal...";
}

//Main.cpp

#include <iostream>
#include "Animal.h"
#include "Array.h"

std::ostream& operator<<(std::ostream&, const Animal&);
void IntFillFunction(Array<int>& theArray);
void AnimalFillFunction(Array<Animal>& theArray);

int main()
{
  Array<int> intArray;
  Array<Animal> animalArray;
  IntFillFunction(intArray);
  AnimalFillFunction(animalArray);
  std::cout << "intArray...\n" << intArray;
  std::cout << "\nanimalArray...\n" << animalArray << std::endl;

  std::cin.get();

  return 0;
}

std::ostream& operator<<(std::ostream& theStream, const Animal& theAnimal)
{
  theStream << theAnimal.GetWeight();
  return theStream;
}

void IntFillFunction(Array<int>& theArray)
{
  bool Stop = false;
  int offset, value;
  while (!Stop)
  {
      std::cout << "Enter an offset (0-9) and a value. ";
      std::cout << "(-1 to stop): ";
      std::cin >> offset >> value;
      if (offset < 0)
          break;
      if (offset > 9)
      {
          std::cout << "***Please use values between 0 and 9.***\n";
          continue;
      }
      theArray[offset] = value;
  }
}

void AnimalFillFunction(Array<Animal>& theArray)
{
  Animal *pAnimal;
  for (int i = 0; i < theArray.GetSize(); i++)
  {
      pAnimal = new Animal(i * 10);
      theArray[i] = *pAnimal;
      delete pAnimal;
  }
}

我已尽力通过向您提供所需的程序行为、特定问题或错误以及重现它所需的最短代码来使这个问题切题。所有这些都是 Help Center 页面中记录的调试帮助的要求。 我是这个网站的新手,如果我的问题仍然离题,请告诉我如何更改我的问题以使其更贴近主题,或者告诉我一个更好的地方来问我的问题。 - 谢谢

此函数在 Array class 声明之前声明(即,编译器从未见过该类型并且不知道它是什么,因此您的错误)。

template<typename> class Array; // Add this forward declaration

template <typename T>
std::ostream& operator<< (std::ostream&, const Array<T>&);

编辑

我刚刚注意到 operator<<Array class 之前声明并且作为 Array class 中的友元函数。您可以删除顶部的声明。

编辑 2

Array.h

我删除了以下项目

#include "Animal.h"

template <typename T>
std::ostream& operator<< (std::ostream&, const Array<T>&);

Array<Animal>::Array(int AnimalArraySize) :itsSize(AnimalArraySize)
{
  pType = new Animal[AnimalArraySize];
}

友元函数声明更新为

template<typename T> // This is not a member function so must be declared as a template
friend std::ostream& operator<< (std::ostream&, const Array<T>&);

Animal.h

这个class有friend函数,但是没有在cpp文件中实现。我将定义从 main.cpp 移到了 Animal.cpp