你知道吗,如何为运营商写一个函数或方法的签名<<用于C ++中的模板类?我想要类似的东西:
template <class A> class MyClass{
public:
friend ostream & operator<<(ostream & os, MyClass<A> mc);
}
ostream & operator<<(ostream & os, MyClass<A> mc){
// some code
return os;
}
但这只是不会编译。有谁知道,怎么写得正确?
答案 0 :(得分:6)
以下所述,如果您不需要操作员成为朋友,那么请不要将其变成朋友。特别是对于输出操作员,在我看来,你不应该让他们成为朋友。这是因为如果您的类可以输出到流,它应该具有等效的get
函数,以编程方式提供相同的数据。在这种情况下,您可以根据operator<<
函数将get
写为非朋友。
如果你有充分的理由让他们成为朋友,你可以做朋友定义
template <class A> class MyClass {
public:
friend ostream & operator<<(ostream & os, MyClass<A> const& mc) {
// ...
}
};
这样您就不需要template<...>
子句来获取类型A
。如果你在模板中定义运算符,我们知道这一点。请注意,即使您在模板中定义了它,它也不是成员函数。它仍然是非成员,但可以访问类中声明的名称(如模板参数)。对于您创建的MyClass
的每个实例,将从打印内容的朋友函数创建一个不同的非模板运算符函数。
如果要在外部定义模板,则必须预先声明它才能将其作为朋友声明给定的特化。
// predeclare it so you can make it a friend.
template <class A> class MyClass;
template <class A> ostream &operator<<(ostream &os, MyClass<A> const&);
template <class A> class MyClass{
public:
/* the "<A>" is needed - it says that a given instantiation of
that template is a friend, and not a non-template function. */
friend ostream & operator<< <A>(ostream & os, MyClass<A> const& mc);
};
template <class A>
ostream & operator<<(ostream & os, MyClass<A> const& mc){
// some code
return os;
}
这使operator<< <Foo>
成为MyClass<Foo>
的朋友。如果您要省略<A>
或者也可能省略空<>
,编译器会理解为您说非模板运算符具有具体而不是模板化参数朋友。
更简单但不太“正确”的解决方案是让MyClass <Foo>
成为所有operator <<
实例的朋友。因此理论上operator << <Bar>
可以访问MyClass <Foo>
的私有成员。这不是想要的东西,但它也有效,获得了比需要更多的访问权限。它摆脱了向前声明的需要:
template <class A> class MyClass{
public:
/* make all instantiations friends. */
template<typename T>
friend ostream & operator<<(ostream & os, MyClass<T> const& mc);
};
template <class T>
ostream & operator<<(ostream & os, MyClass<T> const& mc){
// some code
return os;
}