模板在使用之前必须先声明。模板的使用由友元声明构成,不是由模板的声明构成。实际的模板声明必须在友元声明之前。例如,编译系统尝试链接以下示例中生成的对象文件时,对未实例化的 operator<< 函数,会生成未定义错误。
示例 6-2 友元声明问题的示例array.h
// generates undefined error for the operator<< function
#ifndef ARRAY_H
#define ARRAY_H
#include <iosfwd>
template<class T> class array {
int size;
public:
array();
friend std::ostream&
operator<<(std::ostream&, const array<T>&);
};
#endif
array.cc
#include <stdlib.h>
#include <iostream>
template<class T> array<T>::array() {size = 1024;}
template<class T>
std::ostream&
operator<<(std::ostream& out, const array<T>& rhs)
{return out <<’[’ << rhs.size <<’]’;}
main.cc
#include <iostream>
#include "array.h"
int main()
{
std::cout
<< "creating an array of int... " << std::flush;
array<int> foo;
std::cout << "done\n";
std::cout << foo << std::endl;
return 0;
}
请注意,因为编译器将以下行作为普通函数(array 类的 friend)的声明进行读取,所以编译期间不会出现错误消息。
friend ostream& operator<<(ostream&, const array<T>&);
因为 operator<< 实际上是模板函数,所以需要在声明 template class array 之前提供模板声明。但是,由于 operator<< 有一个 typearray<T> 的参数,因此必须在声明函数之前声明 array<T>。文件 array.h 必须如此示例所示:
#ifndef ARRAY_H
#define ARRAY_H
#include <iosfwd>
// the next two lines declare operator<< as a template function
template<class T> class array;
template<class T>
std::ostream& operator<<(std::ostream&, const array<T>&);
template<class T> class array {
int size;
public:
array();
friend std::ostream&
operator<< <T> (std::ostream&, const array<T>&);
};
#endif