我试图将我的模板化类的模板化成员函数的声明和定义分开,但最终出现了以下错误和警告。
template <typename I>
class BigUnsigned{
const size_t cell_size=sizeof(I);
std::vector<I> _integers;
public:
BigUnsigned();
BigUnsigned(I);
friend std::ostream& operator<<(std::ostream& out, const BigUnsigned& bu);
};
std::ostream& operator<<(std::ostream& out, const BigUnsigned& bu){
for (auto integer : bu._integers){
out<<integer<<std::endl;
}
return out;
}
../HW06/BigUnsigned.h:13:77:警告:友元声明“std::oStream&operator<<(std::oStream&,const BigUnsigned&)”声明了一个非模板函数[-wnon-template-friend]友元std::oStream&operator<<(std::oStream&out,const BigUnsigned&bu);^../Hw06/BigUnsigned.h:13:77:注意:(如果这不是您想要的,请确保函数模板已经声明,并在此处的函数名后面添加<>)../Hw06/BigUnsigned.h:16:51:错误:在没有参数列表的情况下使用模板名“BigUnsigned”无效<<(std::Ostream&out,const BigUnsigned&bu){^../Hw06/BigUnsigned.h:In函数“std::Ostream&out,const Int&)”:../Hw06/BigUnsigned.h:在“bu”中请求成员“_integers”,该成员是非类
当我加入这样的声明和定义时,一切都编译得很好。
template <typename I>
class BigUnsigned{
const size_t cell_size=sizeof(I);
std::vector<I> _integers;
public:
BigUnsigned();
BigUnsigned(I);
friend std::ostream& operator<<(std::ostream& out, const BigUnsigned& bu){
for (auto integer : bu._integers){
out<<integer<<std::endl;
}
return out;
}
};
目的是将成员variableintegers打印到cout。可能是什么问题?
附注:使用这个问题,我使函数免费,但没有帮助。
bigunsigned
是模板类型,因此
std::ostream& operator<<(std::ostream& out, const BigUnsigned& bu)
不会工作,因为没有bigunsigned
。您需要使friend函数成为一个模板,以便可以使用不同类型的bigunsigned
。
template <typename I>
class BigUnsigned{
const size_t cell_size=sizeof(I);
std::vector<I> _integers;
public:
BigUnsigned();
BigUnsigned(I);
template<typename T>
friend std::ostream& operator<<(std::ostream& out, const BigUnsigned<T>& bu);
};
template<typename T>
std::ostream& operator<<(std::ostream& out, const BigUnsigned<T>& bu){
for (auto integer : bu._integers){
out<<integer<<std::endl;
}
return out;
}
第二个示例起作用的原因是,由于它是在类内部声明的,所以它使用了类使用的模板类型。
NathanOliver对答案的改进。
对于另一个答案,函数模板的所有实例化都是类模板的所有实例化的friend
s。
运算符<
是bigunsigned
和bigunsigned
的朋友
。
运算符<
是bigunsigned
以及bigunsigned
的友元
。
您可以稍微更改声明,以便
运算符<
是bigunsigned
的朋友
但不是bigunsigned
的。
运算符<
是bigunsigned
的友元
但不是bigunsigned
。
// Forward declaration of the class template.
template <typename I> class BigUnsigned;
// Forward declaration of the function template
template <typename I>
std::ostream& operator<<(std::ostream& out, const BigUnsigned<I>& bu);
// Change the friend-ship declaration in the class template.
template <typename I>
class BigUnsigned{
const size_t cell_size=sizeof(I);
std::vector<I> _integers;
public:
BigUnsigned();
BigUnsigned(I);
// Grant friend-ship only to a specific instantiation of the
// function template.
friend std::ostream& operator<< <I>(std::ostream& out, const BigUnsigned<I>& bu);
};
要添加第三个改进可读性的变体,请在类中定义friend函数:
#include <iostream>
template <typename T>
class Foo {
int test = 42;
// Note: 'Foo' inside the class body is basically a shortcut for 'Foo<T>'
// Below line is identical to: friend std::ostream& operator<< (std::ostream &os, Foo<T> const &foo)
friend std::ostream& operator<< (std::ostream &os, Foo const &foo) {
return os << foo.test;
}
};
int main () {
Foo<int> foo;
std::cout << foo << '\n';
}