2009-10-21 72 views
9

我有一个问题,如果我有一个模板类,它又有一个模板方法,该类的另一个实例的类参数(具有不同的模板参数),它不能访问受保护或类的私有成员作为参数传递,例如:模板的C++类成员访问问题

template<typename T>class MyClass 
{ 
    T v; 
public: 
    MyClass(T v):v(v){} 

    template<typename T2>void foo(MyClass<T2> obj) 
    { 
     std::cout << v  << " "; 
     //error C2248: 'MyClass<T>::v' : cannot access private member declared in class 'MyClass<T>' 
     std::cout << obj.v << " "; 
     std::cout << v + obj.v << std::endl; 
    } 
}; 
int main() 
{ 
    MyClass<int> x(5); 
    MyClass<double> y(12.3); 
    x.foo(y); 
} 

有什么方法说,在MyClass的<牛逼>方法可以完全访问MyClass的<SomeOtherT>?

回答

9

它们是不同的类型:模板构造新的类型从模板。

你必须让你的朋友的类实例化其他:

template <typename T>class MyClass 
{ 
    T v; 
public: 
    MyClass(T v):v(v){} 

    template<typename T2>void foo(MyClass<T2> obj) 
    { 
     std::cout << v  << " "; 
     std::cout << obj.v << " "; 
     std::cout << v + obj.v << std::endl; 
    } 

    // Any other type of MyClass is a friend. 
    template <typename U> 
    friend class MyClass; 

    // You can also specialize the above: 
    friend class MyClass<int>; // only if this is a MyClass<int> will the 
           // other class let us access its privates 
           // (that is, when you try to access v in another 
           // object, only if you are a MyClass<int> will 
           // this friend apply) 
}; 
+0

欢乐合唱团! :D [15char] – GManNickG 2009-10-21 07:21:07

+0

您的代码实际上并未在Comeau中编译,而且我无法找到Standard如何允许它。由于14.5.3/3,我认为'friend'之前的'template'是必要的。 – 2009-10-21 07:24:45

+0

我其实也是这么做的:(我删除它,因为我认为这是没有必要的(在VS中测试后)我真的不应该用这个测试...我会重新加入它。Bah! – GManNickG 2009-10-21 07:29:07

7

添加MyClass为好友等级:

​​

根据C++标准14.5.3/3:

朋友模板可以在类或类模板中声明。朋友函数模板可以在类或类模板中定义,但朋友类模板不能在类或类模板中定义。在这些情况下,朋友类或朋友功能模板的所有特化都是授予友谊的类或类模板的朋友。 [示例:

class A { 
    template<class T> friend class B; // OK 
    template<class T> friend void f(T){ /* ... */ } // OK 
}; 

末端示例]

注意:您应该知道,上面依然代码可能会导致错误在某些编译由于Core Issue #602这仍然是开放的。尽管如此,上面的代码在GCC,Visual C++和Comeau上编译。

为了唯一的功能foo的朋友,你可以写:

template<typename T> class MyClass 
{ 
    template<typename TY> template<typename TX> 
    friend void MyClass<TY>::foo(MyClass<TX>); 
... 
+0

因此,该代码使得MyClass的的MyClass的所有TX。 的朋友是否有可能使只有MyClass的 :: foo的朋友,而不是整个类? – user200783 2009-10-21 07:29:15

+0

@保罗,我已经更新了答案。 – 2009-10-21 10:04:10