如何让方法访问其他模板类实例的私有成员?

时间:2014-10-17 09:59:15

标签: c++ templates private-members

这个非常小的示例将无法编译,因为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?),但由于我只有一种需要访问的方法(如示例所示),我宁愿限制对这种方法的友谊。这可能吗?

2 个答案:

答案 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;
}

Live example (gcc one Ideone)


请注意,与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;
}

Example