2014-10-17 102 views
8

这极小的例子将无法编译,因为A<int>不能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; 
} 

访问私有成员i我知道,我可以让对方(见:How to access private members of other template class instances?)的所有模板实例朋友,但因为我只有一种方法需要访问权限(如示例中所示),我宁愿将友谊限制为该方法。这可能吗?

+1

致敬:我想知道我能做些什么来改善问题! – DarioP 2014-10-17 10:26:22

+0

这两个答案和问题本身都默默地降低了;我怀疑它与内容无关。 – Angew 2014-10-17 10:35:50

回答

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)


注意,与海湾合作委员会,clang rejects the code。尽管如此,我无法在标准中找到任何会使其失效的内容。

+0

这就是我的尝试,但它不起作用(不downvoter) – jrok 2014-10-17 10:06:51

+0

@jrok适用于我(呃,对于Ideone GGC)。 – Angew 2014-10-17 10:07:36

+0

@PiotrS。那么为什么没有“朋友”声明它不工作?我测试了这一点。 – Angew 2014-10-17 10:08:25

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

it works on gcc

这个问题似乎是一个clang的代表朋友类模板的问题,其中依赖名称说明符无法在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

+1

我认为即使在编辑之前这是一个有价值的答案(当我删除它时,我感觉不好),但现在更好! – DarioP 2014-10-17 10:52:09

相关问题