以下代码不起作用,因为t
成员函数无法访问其参数对象的属性。
如何将模板类A的模板方法t声明为A?
的友元函数对于没有模板的代码,不需要声明朋友。
代码:
template <typename T>
class A{
protected:
T a;
public:
A(int i){
a = i;
}
template <typename T1>
void t(const A<T1> & Bb){
a = Bb.a;
}
};
int main(void){
A<int> Aa(5);
A<float> Bb(0);
Aa.t(Bb);
}
编译器错误(icc test.cpp):
test.cpp(11): error #308: member "A<T>::a [with T=float]" (declared at line 4) is inaccessible
a = Bb.a;
^
detected during instantiation of "void A<T>::t(const A<T1> &) [with T=int, T1=float]" at line 17
没有模板的代码:
class A{
protected:
int a;
public:
A(int i){
a = i;
}
void t(const A & Bb){
a = Bb.a;
}
};
int main(void){
A Aa(5);
A Bb(0);
Aa.t(Bb);
}
答案 0 :(得分:3)
您可以让所有模板实例化彼此成为朋友。
template <typename T>
class A {
protected:
// This makes A<int> friend of A<float> and A<float> friend of
// A<int>
template <typename T1> friend class A;
T a;
public:
A(int i){
a = i;
}
template <typename T1>
void t(const A<T1> & Bb){
a = Bb.a;
}
};
int main(void){
A<int> Aa(5);
A<float> Bb(0);
Aa.t(Bb);
}
答案 1 :(得分:1)
A<T>
和A<T1>
是两种不同的类型,如果T
和T1
是两种不同的类型。在这种情况下,您也可以将A<T>
替换为Foo
,将A<T1>
替换为Bar
。在这一点上,为什么你需要让Foo和Bar成为朋友(ehm,A<T>
和A<T1>
,其中T
和T1
不是同一类型,这应该是相当明显的)
现在,看看你的错误:
detected during instantiation of "void A<T>::t(const A<T1> &) [with T=int, T1=float]"
它告诉你它在t()
类型的对象上调用你的A<T>
函数,传入A<T1>
类型的对象作为参数,其中T=int
和{{ 1}}。这使得调用不同类(T1=float
)的函数的对象比用作参数(A<int>
)的对象的类,并且因为它们是不同的类,所以它们不能在没有朋友的情况下访问彼此的受保护成员。