将模板参数作为模板类的友元

Making a template parameter as friend of template class

本文关键字:友元 参数      更新时间:2023-10-16

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

第三方标头

class A
{
    private:
    int i;
};

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

调试打印机.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 声明为我的模板类的朋友并收到此错误

错误:i 无法从 x::acc() 访问

现在我可以通过创建非模板调试打印机来解决此问题,但只是出于好奇,有没有办法创建一个模板类,该模板类将成为其输入类型参数的朋友?

谢谢

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

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

第一件事是,正如其他人提到的,友谊不是对称的,你正在尝试错误的方向(授予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;
};
你可以

宣布T为朋友,但这对你没有任何好处。需要的是您的模板获取 T 中的私有数据的方法,而这反过来:T必须将您的模板声明为朋友。关于友谊的决定是由提供友谊的班级做出的;它不能从另一个班级要求。没有朋友声明,就没有合法的方法可以从外面获取班级的;这就是私人的意思。