【问题标题】:C++ Class member access problem with templates模板的 C++ 类成员访问问题
【发布时间】:2010-12-08 14:56:20
【问题描述】:

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

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

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

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

    你必须对你的班级朋友进行其他实例化:

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

    【讨论】:

    • 欢乐! :D [15char]
    • 您的代码实际上无法在 Comeau 中编译,我无法找到标准如何允许它。我相信 templatefriend 之前是必要的,因为 14.5.3/3。
    • 我实际上也有这个:(我删除它是因为我认为它没有必要。(在VS中测试后)我真的不应该用那个测试......我会把它重新添加进去。呸!
    • 我也在 VS 中测试过,但即使在 C++0x 草案 N2857 中我也找不到这样的语法。应该是VS允许它的某种原因。
    • @Kiril:: 一般都是因为VC有bug。 :(
    【解决方案2】:

    添加MyClass为好友类:

    template<typename T> class MyClass
    {
        template<typename TX>
        friend class 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>);
     ...
    

    【讨论】:

    • 因此,这段代码使 MyClass 成为所有 TX 的 MyClass 的朋友。是否可以只让 MyClass::foo 成为朋友而不是整个班级?
    猜你喜欢
    • 1970-01-01
    • 2017-11-27
    • 2013-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-08
    • 2020-08-23
    相关资源
    最近更新 更多