将模板参数设为模板类的朋友

时间:2013-09-23 12:30:59

标签: c++ templates friend

我正在调试一个与第三方库交互的应用程序,其代码不可用,只有标题和.so可用。现在我可以将它加载到调试器中并检查在第三方库中声明的类的私有成员的变量值,但由于对象的数量很大,我想创建一些机制在控制台上打印它,我可以稍后分析。 我想出了类似的东西

ThirdPartyHeader

class A
{
    private:
    int i;
};

我没有在上面的课程中包含额外的细节

Debugprinter.cpp

#include <thirdpartheaders>

template <typename T> class debugprinter
{
    friend class T;
    public :
    void printonconsole()
    {
        T a;
        std::cout << std::endl << a.i << std::endl;
        return;
    }
}

现在我尝试在上面编译,但似乎我不能将未定义的类型T声明为我的模板类的朋友并得到此错误

错误:无法从x :: acc()

访问我

现在我可以通过创建非模板调试程序来解决这个问题但是出于好奇,有没有办法可以创建一个模板类,它会成为输入类型参数的朋友?

由于

3 个答案:

答案 0 :(得分:4)

A声明为debugprinter<A>的朋友无济于事。 friend关系不对称。这种关系只是单向的。如果您想访问debugprinter<A>的私人成员,则需要A成为A的朋友。为此,您需要修改类A本身。

就像现实世界的友谊一样。你不能强迫别人成为你的朋友。你只能对别人表现友好。

答案 1 :(得分:3)

您可以将T声明为朋友,但对您没有任何好处。我们需要的是让您的模板获取T中的私有数据的方式,反之亦然:T必须将您的模板声明为朋友。关于友谊的决定是由提供友谊的班级做出的;它不能从另一个班级要求。如果没有朋友的声明,就没有合法的方式可以从外面获得一个班级的私人部分;这就是私人的意思。

答案 2 :(得分:2)

第一件事是,正如其他人所说,友谊不是对称的,你正在尝试错误的方向(授予A访问权限debugprinter<A>。这就是说,而且只是为了搜索的人问题:

在旧版本的标准(C ++ 03)中,不可能直接将模板参数声明为朋友。在C ++ 11中解除了这一限制,尽管它需要稍微不同的语法:

template <typename T>
class test {
   friend T;             // note, not 'friend class T'!!!
};

但是,在C ++ 03中,您可以通过使用一个额外的间接级别来实现相同的行为。你不能成为模板参数的朋友,但你可以成为一个依赖类型的朋友,通过使用identity元函数你可以实现你想要的:

template <typename T>
struct identity {
   typedef T type;
};
template <typename T>
class test {
   friend class identity<T>::type;
};