我写了一段代码:
#include <iostream>
#include <cassert>
using namespace std;
template<typename T>
class dynArray{
int size;
T* ptr;
public:
dynArray(int n=0);
~dynArray();
T& operator[] (const int index);
friend ostream& operator<<<T>(ostream& os,const dynArray<T>& A);
};
template<typename T> dynArray<T>::dynArray(int n):size(n){
if (size==0)
{
cout << "Size Zero"<< endl;
ptr=NULL;}
else
{
try{
ptr = new T[size];
cout << "Constructor Called" << endl;
}
catch(bad_alloc xa)
{
cout << "Allocation Failure" <<endl;
exit(EXIT_FAILURE);
}
}
}
template<typename T> dynArray<T>::~dynArray(){
cout << "Destructor Called for array of size : " << size << endl;
delete[] ptr;
}
template<typename T> T& dynArray<T>::operator[] (const int index){
assert(index >=0 && index <size);
return *(ptr+index);
}
template<typename T> ostream& operator<< <T>(ostream& os,const dynArray<T>& A){
for (int i=0; i < A.size ; i++)
os << *(A.ptr+i) << " ";
return os;
}
int main()
{
dynArray<int> array1;
dynArray<int> array2(5);
array2[0]=15;
array2[3]= 45;
cout << array2 << endl;
return 0;
}
但是在编译错误时:
$ g++ -Wall DynArray.cpp -o DynArray
DynArray.cpp:46: error: partial specialization `operator<< <T>' of function template
DynArray.cpp: In instantiation of `dynArray<int>':
DynArray.cpp:54: instantiated from here
DynArray.cpp:14: error: template-id `operator<< <int>' for `std::basic_ostream<char, std::char_traits<char> >& operator<<(std::basic_ostream<char, std::char_traits<char> >&, const dynArray<int>&)' does not match any template declaration
DynArray.cpp: In function `std::ostream& operator<<(std::ostream&, const dynArray<T>&) [with T = int]':
DynArray.cpp:61: instantiated from here
DynArray.cpp:8: error: `int dynArray<int>::size' is private
DynArray.cpp:47: error: within this context
DynArray.cpp:9: error: `int*dynArray<int>::ptr' is private
DynArray.cpp:48: error: within this context
我认为operator<<
的模板语法错误。有人可以帮忙吗?无法弄清楚错误在哪里。
答案 0 :(得分:2)
您不能friend
未声明的模板功能的专业化。您需要事先声明operator <<
。当然要这样做,你需要已经声明dynArray
。这一堆前向声明看起来像这样(Live at Coliru):
template<typename T> class dynArray;
template<typename T>
ostream& operator << (ostream& os, const dynArray<T>& A);
template<typename T>
class dynArray {
// ...
friend ostream& operator<< <T>(ostream& os, const dynArray& A);
};
作为@ooga points out in his comment,朋友声明中的模板参数是不必要的;编译器可以推导出它们。您可以简单地将其声明为:
friend ostream& operator<< <> (ostream& os, const dynArray& A);
我个人觉得这个语法在这个例子中有点标点符号。
或者,如果您发现前向声明具有攻击性,则可以通过在类定义(Coliru again)中定义它来为dynArray
的每个专门化声明一个单独的非模板友元函数:
template<typename T>
class dynArray {
// ...
friend ostream& operator<< (ostream& os,const dynArray& A) {
for (int i=0; i < A.size ; i++)
os << *(A.ptr+i) << " ";
return os;
}
};
答案 1 :(得分:1)
在类中声明朋友为: -
template<typename U>
friend ostream& operator<<(ostream& os,const dynArray<U>& A);
并将其定义为: -
template<typename U>
ostream& operator<< (ostream& os,const dynArray<U>& A){...}
请参阅HERE