将c ++非模板类的朋友作为模板类的成员

时间:2018-11-09 07:03:16

标签: c++ templates friend

我是新来的使用模板的人。作为标题,我有一个非模板类(Obj和ObjBase)和一个模板类PItem。我想让PITem :: RefValue()访问Obj中的私有成员。

我认为下面的方法可以工作:

   template<class T>
   friend int PItem<T>::getValue();

不是:

  

错误C2248:'Obj :: getValue':无法访问在类'Obj'中声明的私有成员

     

注意:请参见对正在编译的函数模板实例化'int PItem :: getValue(void)'的引用

编译器投诉:

   if (ptr) return ptr->getValue();
class ObjBase
{
public:
    ObjBase() {}
    ~ObjBase(){}
protected:
    int  value{0};
};

class Obj : public ObjBase
{
    template<class T>
    class PItem;

    template<class T>
    friend int PItem<T>::getValue();

public:
    Obj(int i) { value = i; };
    ~Obj() {};

private:
    int getValue()
    {
        return value;
    }
};

template<typename T>
class PItem
{
public:
    PItem(T* t) { ptr = t; }
    ~PItem() {}
    int getValue() {
        if (ptr) return ptr->getValue();
        return -1;
    }
    T* ptr;
};

1 个答案:

答案 0 :(得分:3)

您要在PItem内声明一个嵌套的类模板Obj,然后friend声明会引用它,而不是在globle范围内定义的模板。

您应该删除嵌套的类模板声明,并将PItem的定义移到Obj的定义之前;因为friend声明要求PItem为完整类型。

template<typename T>
class PItem
{
public:
    PItem(T* t) { ptr = t; }
    ~PItem() {}
    int getValue() {
        if (ptr) return ptr->getValue();
        return -1;
    }
    T* ptr;
};

class Obj : public ObjBase
{

    template<class T>
    friend int PItem<T>::getValue();

public:
    Obj(int i) { value = i; };
    ~Obj() {};

private:
    int getValue()
    {
        return value;
    }
};

LIVE