C++ 模板类的某些友元函数显示未定义的引用
最初正在处理其他人先前提出的一个问题:。看到OP没有完全利用C++ 模板类的某些友元函数显示未定义的引用,c++,templates,friend,friend-function,C++,Templates,Friend,Friend Function,最初正在处理其他人先前提出的一个问题:。看到OP没有完全利用DataOut和GetData的模板,所以我也尝试将它们作为模板 以下是我最终得到的代码: #包括 #包括 模板 类数组{ 公众: tu[10]; 友元无效数据输出(常量数组&); friend void GetData(数组&); }; 模板 无效数据输出(常量数组和arr){ 标准::cout>arr.U[0]; std::cin.clear(); } int main(){ 阵列Arr1; Getdata(Arr1); 数据输出(
DataOut
和GetData
的模板,所以我也尝试将它们作为模板
以下是我最终得到的代码:
#包括
#包括
模板
类数组{
公众:
tu[10];
友元无效数据输出(常量数组&);
friend void GetData(数组&);
};
模板
无效数据输出(常量数组和arr){
标准::cout>arr.U[0];
std::cin.clear();
}
int main(){
阵列Arr1;
Getdata(Arr1);
数据输出(Arr1);
}
但是,我得到了对DataOut
的未定义引用:main.cpp:(.text+0x3a):对'DataOut(Array const&')的未定义引用。
我找到了两种方法来解决这个问题:
数组
类中定义数据输出
DataOut
,而不仅仅是DataOut
问题是,为什么
GetData
没有发生错误?我还尝试按不同的顺序调用和定义它们,但结果仍然相同
有什么我遗漏的吗?或者是我的编译器(clang7.0.0
)的错误?您声明了两个(系列)非模板友元函数
template<class T>
class Array{
public:
T U[10];
friend void DataOut(const Array&);
friend void GetData(Array&);
};
例如,如果您将在main中添加以下语句
f( A<long>() );
f(A());
然后编译器将发出错误,因为没有这样的非模板函数。类模板的这种专门化的函数没有定义
您可以在类中定义friend非模板函数。在这种情况下,编译器将为类模板的每个专门化实例化所谓的模板化实体
这就是函数模板声明
template<class T>
void DataOut(const Array<T>& arr){
std::cout << arr.U[0];
}
模板
无效数据输出(常量数组和arr){
std::coutVlad回答了我的大部分问题。同时,我从一些gcc警告中找到了如何将friend函数定义为模板函数:
template<class T>
class Array; // Forward declaration of the Array<T> class
template<class T>
void DataOut(const Array<T>& arr){
std::cout << arr.U[0];
}
template<class T>
class Array{
public:
T U[10];
friend void DataOut<>(const Array<T>&); // `<>` used right after `DataOut`
}
模板
class Array;//数组类的前向声明
模板
无效数据输出(常量数组和arr){
std::cout@Ranoiaetep您是否看到GetData和GetData是两个不同的名称?也就是说,您输入了一个错误,并声明了两个具有不同名称的函数。请注意,这使friend成为一个模板。在OP中,它不是。这可能会导致一些行为更改。
template<class T>
void DataOut(const Array<T>& arr){
std::cout << arr.U[0];
}
template<class T>
class Array; // Forward declaration of the Array<T> class
template<class T>
void DataOut(const Array<T>& arr){
std::cout << arr.U[0];
}
template<class T>
class Array{
public:
T U[10];
friend void DataOut<>(const Array<T>&); // `<>` used right after `DataOut`
}