这个非常小的示例将无法编译,因为A<int>
无法访问i
中的私有成员A<double>
template <class T>
class A {
int i;
public:
template <class U>
void copy_i_from( const A<U> & a ){
i = a.i;
}
};
int main(void) {
A<int> ai;
A<double> ad;
ai.copy_i_from(ad);
return 0;
}
我知道我可以让所有模板实例彼此成为朋友(参见:How to access private members of other template class instances?),但由于我只有一种需要访问的方法(如示例所示),我宁愿限制对这种方法的友谊。这可能吗?
答案 0 :(得分:8)
是的,这是可能的。会员功能通常可以指定为朋友。
template <class T>
class A {
int i;
public:
template <class U>
void copy_i_from( const A<U> & a ){
i = a.i;
}
template <class F>
template <class U>
friend void A<F>::copy_i_from(const A<U> & a);
};
int main(void) {
A<int> ai;
A<double> ad;
ai.copy_i_from(ad);
return 0;
}
请注意,与gcc不同,clang rejects the code。但是,我无法在标准中找到使其无效的任何内容。
答案 1 :(得分:6)
似乎如果你想拥有一个朋友会员功能,以下内容不会对clang起作用:
template <class T>
class A {
int i;
public:
template <class U>
void copy_i_from( const A<U> & a ){
i = a.i;
}
template <class F>
template <class U> friend void A<F>::copy_i_from(const A<U> & a);
};
int main(void) {
A<int> ai;
A<double> ad;
ai.copy_i_from(ad);
return 0;
}
while it works on gcc。
这个问题似乎是代表朋友类模板的一个铿锵的问题,在AST中无法解析依赖名称说明符:http://llvm.org/klaus/clang/commit/8b0fa5241a0416fc50dfbb7e38f20e777f191848/(在编写本文时仍然在主干中)。
因此你可以使用上面的成员函数版本,虽然它可能不适用于clang,直到找到它。
计划-B解决方案是让它具有免费的模板化朋友功能,虽然它可能不是你想要的(被cland和gcc都接受):
#include <iostream>
using namespace std;
template <class T>
class A {
int i;
public:
template<class V, class U>
friend void copy_i_from(A<V>& t, const A<U> & a);
};
template<class V, class U>
void copy_i_from(A<V>& t, const A<U> & a){
t.i = a.i;
}
int main(void) {
A<int> ai;
A<double> ad;
copy_i_from(ai,ad);
return 0;
}