使用模板时,如何修复以下编译器错误以实现程序的预期行为?
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
我正在练习 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