【问题标题】:Making a template parameter as friend of template class将模板参数作为模板类的朋友
【发布时间】:2013-09-28 08:25:15
【问题描述】:

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

第三方标头

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() 访问 i

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

谢谢

【问题讨论】:

  • 如果您不能将A 修改为将debugprinter 设为好友,则没有标准的解决方案来访问A 的私人成员。您可以使用的所有技术都是未定义的行为。

标签: c++ templates friend


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 不,我不能将 T 声明为模板类的友元类,因为友元声明需要详细的类型说明符
    • 但是你得到错误信息的原因不是朋友声明不起作用,而是即使它起作用了,它也对你没有帮助。
    【解决方案3】:

    第一件事是,正如其他人提到的那样,友谊不是对称的,并且您正在尝试错误的方向(授予 A 访问 debugprinter&lt;A&gt; 的权限。话虽如此,只是为了人们搜索问题:

    在旧版本的标准 (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;
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-08
      • 2014-10-03
      • 1970-01-01
      • 2010-10-16
      • 1970-01-01
      • 2020-01-28
      • 2021-09-11
      相关资源
      最近更新 更多