C++中在类中重载输出运算符时遇到error: declaration of ‘class T‘的问题的解决

2023-11-18

一、问题代码及报错提示:

​
#include <iostream>

using namespace std;

template<class T>
class Person{
public:
    template<class T>
    friend ostream& operator<<(ostream& out,Person<T> &p);
public:
    //重载输出运算符
    Person(T age,T id);
    void Show();
private:
    T mAge;
    T mID;
};
template<class T>
Person<T>::Person(T age,T id)
{
    this->mAge = age;
    this->mID = id;
}
template<class T>
void Person<T>::Show()
{
    cout<<"mAge:"<<this->mAge<<" "<<"mID"<<this->mID<<endl;
}
template<class T>
ostream& operator<<(ostream& out,Person<T> &p)
{
    out<<"mAge:"<<p.mAge<<" "<<"mID"<<p.mID<<endl;
    return out;
}

void test01()
{
    Person<int> p(20,10);
   // p.Show();
    cout<<p;

}

int main(int argc, char *argv[])
{
    test01();
    cout << "Hello World!" << endl;
    return 0;
}

​

 二、原因剖析

因为代码中用到类模板template<class T>而在类内声明的友元函数也用到了<T>,此时友元函数是依赖于类的实现的,所以编译器会报错

对此我们有几种解决方案:

1.改变友元与类模板的对应关系为多对多(若类模板使用的是template<class T>,友元函数就使用template<class U>来实现),代码如下:

#include <iostream>

using namespace std;

template<class T>
class Person{
public:
    template<class U>
    friend ostream& operator<<(ostream& out,Person<U> &p);
public:
    //重载输出运算符
    Person(T age,T id);
    void Show();
private:
    T mAge;
    T mID;
};
template<class T>
Person<T>::Person(T age,T id)
{
    this->mAge = age;
    this->mID = id;
}
template<class T>
void Person<T>::Show()
{
    cout<<"mAge:"<<this->mAge<<" "<<"mID"<<this->mID<<endl;
}
template<class U>
ostream& operator<<(ostream& out,Person<U> &p)
{
    out<<"mAge:"<<p.mAge<<" "<<"mID"<<p.mID<<endl;
    return out;
}

void test01()
{
    Person<int> p(20,10);
   // p.Show();
    cout<<p;

}

int main(int argc, char *argv[])
{
    test01();
    cout << "Hello World!" << endl;
    return 0;
}

2.改变友元与类模板的关系为一对一(朋友关系被限定在相同类型的实例化)代码如下:

#include <iostream>

using namespace std;
//前置声明
template<class T>
class Person;
template<class T>
ostream& operator<<(ostream& out,Person<T> &p);

template<class T>
class Person{
public:
    friend ostream& operator<<<T>(ostream& out,Person<T> &p);
public:
    Person(T age,T id);
    void Show();
private:
    T mAge;
    T mID;
};
template<class T>
Person<T>::Person(T age,T id)
{
    this->mAge = age;
    this->mID = id;
}
template<class T>
void Person<T>::Show()
{
    cout<<"mAge:"<<this->mAge<<" "<<"mID"<<this->mID<<endl;
}
template<class T>
ostream& operator<<(ostream& out,Person<T> &p)
{
    out<<"mAge:"<<p.mAge<<" "<<"mID"<<p.mID<<endl;
    return out;
}

void test01()
{
    Person<int> p(20,10);
   // p.Show();
    cout<<p;

}

int main(int argc, char *argv[])
{
    test01();
    cout << "Hello World!" << endl;
    return 0;
}

3.使用普通友元函数PrintPerson来实现,代码如下:

#include <iostream>

using namespace std;

template<class T>
class Person{
public:
    //普通友元函数的声明
    template<class U>
    friend void PrintPerson(Person<U>& p);
public:
    Person(T age,T id);
    void Show();
private:
    T mAge;
    T mID;
};
template<class T>
Person<T>::Person(T age,T id)
{
    this->mAge = age;
    this->mID = id;
}
template<class T>
void Person<T>::Show()
{
    cout<<"mAge:"<<this->mAge<<" "<<"mID"<<this->mID<<endl;
}
//普通友元函数的实现
template<class U>
void PrintPerson(Person<U>& p)
{
    cout<<"mAge:"<<p.mAge<<" "<<"mID"<<p.mID<<endl;
}
void test01()
{
    Person<int> p(20,10);
   // p.Show();
    //cout<<p;
    PrintPerson(p);

}

int main(int argc, char *argv[])
{
    test01();
    cout << "Hello World!" << endl;
    return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++中在类中重载输出运算符时遇到error: declaration of ‘class T‘的问题的解决 的相关文章

  • Windows 10 Mobile (10.0.14393) 地理围栏后台任务 (LocationTrigger)

    自从10 0 14393 周年纪念更新 LocationTrigger似乎不起作用 我有 Windows Phone 8 1 应用程序 也适用于 UWP 应用程序 输出到的便携式库Windows Runtime Component图书馆 w
  • 内联函数/方法

    声明 内联函数必须在调用之前定义 这个说法正确吗 EDIT 该问题最初是德语 内联功能穆森 弗 伊赫雷姆 奥夫鲁夫定义 sein 也许它对任何人都有帮助 是的 它是正确的 但只是部分正确 它可能正确地重新构建如下 内联函数必须在每个翻译单位
  • 如何尝试/捕获所有异常

    我正在完成由其他人启动的 UWP 应用程序 该应用程序经常崩溃 我总是陷入困境应用程序 at if global System Diagnostics Debugger IsAttached global System Diagnostic
  • 为什么大多数平台上没有“aligned_realloc”?

    MSVC有自己的非标准函数 aligned malloc aligned realloc and aligned free C 17和C11引入了 std aligned alloc 其结果可以是de分配有free or realloc B
  • (const T v) 在 C 中从来都不是必需的,对吗?

    例如 void func const int i 在这里 const是不必要的 因为所有参数都是按值传递的 包括指针 真的吗 C 中的所有参数确实都是按值传递 这意味着无论您是否包含该参数 实际参数都不会改变const or not 然而
  • 如何创建用于 QML 的通用对象模型?

    我想知道是否有任何宏或方法如何将 Qt 模型注册为 QObject 的属性 例如 我有AnimalModel http doc qt io qt 5 qtquick modelviewsdata cppmodels html qabstra
  • mprotect 之后 malloc 导致分段错误

    在使用 mprotect 保护内存区域后第一次调用 malloc 时 我遇到分段错误 这是执行内存分配和保护的代码片段 define PAGESIZE 4096 void paalloc int size Allocates and ali
  • 带 If 的嵌套 For 循环的时间复杂度

    void f int n for int i 1 i lt n i if i int sqrt n 0 for int k 0 k lt pow i 3 k do something 我的思考过程 执行if语句的次数 sum i 1 to
  • TcpClient 在异步读取期间断开连接

    我有几个关于完成 tcp 连接的问题 客户端使用 Tcp 连接到我的服务器 在接受客户端后listener BeginAcceptTcpClient ConnectionEstabilishedCallback null 我开始阅读netw
  • 从 Code::Blocks 运行程序时出现空白控制台窗口 [重复]

    这个问题在这里已经有答案了 当我尝试在 Code Blocks 中构建并运行新程序时 控制台窗口弹出空白 我必须单击退出按钮才能停止它 它对我尝试过的任何新项目 包括 Hello world 都执行此操作 奇怪的是 它对于我拥有的任何旧项目
  • 2D morton 码编码/解码 64 位

    如何将给定 x y 的莫顿代码 z 顺序 编码 解码为 32 位无符号整数 生成 64 位莫顿代码 反之亦然 我确实有 xy2d 和 d2xy 但仅适用于 16 位宽的坐标 产生 32 位莫顿数 在网上查了很多 但没有找到 请帮忙 如果您可
  • 分配器感知容器和propagate_on_container_swap

    The std allocator traits模板定义了一些常量 例如propagate on container copy move assign让其他容器知道它们是否应该在复制或移动操作期间复制第二个容器的分配器 我们还有propag
  • .NET 客户端中 Google 表格中的条件格式请求

    我知道如何在 Google Sheets API 中对值和其他格式进行批量电子表格更新请求 但条件格式似乎有所不同 我已正确设置请求 AddConditionalFormatRuleRequest formatRequest new Add
  • DataTable:通过 LINQ 或 LAMBDA 进行动态 Group By 表达式

    我有一个数据表 我想在其中对未指定数量的字段进行分组 发生这种情况的原因是用户可以选择他想要分组的字段 所以 实际上 我将选择推入列表中 在这个选择上 我必须对我的数据表进行分组 想象一下这段代码 VB 或 C 都一样 public voi
  • 0-1背包算法

    以下 0 1 背包问题是否可解 浮动 正值和 浮动 权重 可以是正数或负数 背包的 浮动 容量 gt 0 我平均有 这是一个相对简单的二进制程序 我建议用蛮力进行修剪 如果任何时候你超过了允许的重量 你不需要尝试其他物品的组合 你可以丢弃整
  • 初始化 LPCTSTR /LPCWSTR [重复]

    这个问题在这里已经有答案了 我很难理解并使其正常工作 基本上归结为我无法成功初始化这种类型的变量 它需要有说的内容7 2E25DC9D 0 USB003 有人可以解释 展示这种类型的正确初始化和类似的值吗 我已查看此站点上的所有帮助 将项目
  • 使用 HTMLAgilityPack 从节点的子节点中选择所有

    我有以下代码用于获取 html 页面 将网址设置为绝对 然后将链接设置为 rel nofollow 并在新窗口 选项卡中打开 我的问题是关于将属性添加到 a s string url http www mysite com string s
  • C 中带有指针的结构的内存开销[重复]

    这个问题在这里已经有答案了 我意识到当我的结构包含指针时 它们会产生内存开销 这里有一个例子 typedef struct int num1 int num2 myStruct1 typedef struct int p int num2
  • C++、三元运算符、std::cout

    如何使用 C 用三元运算符编写以下条件 int condition1 condition2 condition3 int double result int or double std cout lt lt condition1 resul
  • 在 Xamarin 中获取 OutOfMemoryException

    java lang OutOfMemoryError 考虑增加 JavaMaximumHeapSize Java 执行时内存不足 java exe 我的 Visualstudio Xamarin 项目出现内存不足异常 请帮助我如何解决此问题

随机推荐

  • STM32F429 HAL库移植FreeModbus_RTU详细步骤

    STM32F429 HAL库移FreeModbus RTU详细步骤 开发环境说明 完整工程文件下载地址 移植前提 修改 RS485 c 文件 修改 portserial c 文件 修改 porttimer c 文件 修改 stm32f4xx
  • mysql报错1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL

    今天有个业务要连表查数据来着 很久没写SQL了 写完 满意运行 SELECT ac activity complaints id ac activity id ac content ac complaint time u user uuid
  • oracle临时表空间占用率过高,ORACLE临时表空间太大,如何处理?

    近几天意外发现oracle所在的D盘占用量激增 发现oracle实例mydata下的数据文件temp01 dbf居然达到了30个G temp01 dbf是数据库的临时数据文件 存放在临时表空间temp中 如何减小呢 原因 没有给临时表空间设
  • Android Gradle入门

    Gradle是一款非常优秀的构建系统工具 它的DSL基于Groovy实现 可以让你很方便的通过代码控制这些DSL来达到你构建的目的 其构建的大部分功能都是通过插件的方式来实现 所以非常灵活方便 如果内置插件不能满足你的需求你可以自定义自己的
  • kubernetes基础入门知识点

    今天正式入门学习kubernetes 也就是大名鼎鼎的k8s k就是开头字母 s是结尾字母 中间有8个字母 所以简称为k8s 这一小节学习总结一下Kubernetes的基础入门概念 比较简单 理解为主 一 Kubernetes是什么 Kub
  • Java代码审计入门篇

    作者 i春秋核心白帽yanzmi 原文来自 https bbs ichunqiu com thread 42149 1 1 html 本期斗哥带来Java代码审计的一些环境和工具准备 Java这个语言相对于PHP来说还是比较复杂的 所以一开
  • SIM800C二次开发(EAT开发)------------(3)下载APP文件

    下载步骤有篇比较好的帖子可以更好的认识SIM800C的接口方式和步骤 帖子链接如下 https blog fish2bird com p 1274 SIM800C支持USB下载和UART下载两种方式 SIM800C有两个UART接口 下载使
  • 【GD32F427开发板试用】多路ADC规则组同时采样 DMA进行传输数据 顺带开启FPU浮点运算

    本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动 更多开发板试用活动请关注极术社区网站 作者 Hello eQN7e7 前言 开启浮点运算 加快浮点类型数据计算 使用GD32F427V START开发板的ADC1采样四路电
  • 二极管连接的MOS管

    二极管连接的MOS管 求输出电阻时可以电压 电流负反馈
  • STM32CubeMX安装、使用、配置

    1 在官网下载应用 https www st com 并安装java环境所需软件jre 8u271 windows x64 exe 2 使用cube新建项目 打开file gt new prj 3 Pinout Configuration配
  • 985高校副教授晒年薪,网友:公积金顶我一个月工资了......

    教师的工资一直具有争议性 大家的认知两极分化 有人说教师收入特别高 也有人说教师收入堪堪够生活 不存在谁说假话 而是因为各地区教师薪资水平差异较大 学校属于事业单位 薪资受当地经济水平影响 而教师群体中收入最高的是大学老师 曾经就有一份统计
  • ubuntu21.10搭建ebpf环境,BCC和bpftrace

    1 安装虚拟机 虽说centos是生产环境中的标准系统 但是从个人学习角度还是推荐ubuntu 各种软件安装包都能方便地找到 操作界面时也很漂亮 之前一直在centos7 6上折腾 自己升级内核版本 自己安装各种高版本依赖 有一段时间被折磨
  • JavaScript i++与++i、=+与+=的区别

    i i i 先赋值再自增 i 先自增再赋值 都是表达式 i i 1 题目 var a 10 b 20 c 30 a a e a b c a 结果 77 表达式 A B B转化为数字 赋值给A 表达式 A B A A B let x 2 y
  • 会计计算机二级考试试题,计算机二级考试MS-Office考试题库--excle--有答案.docx

    请在 答题 菜单下选择 进入考生文件夹 命令 并按照题目要求完成下面的操作 注意 以下的文件必须保存在考生文件夹下 小蒋是一位中学教师 在教务处负责初一年级学生的成绩管理 由于学校地处偏远地区 缺乏必要的教学设施 只有一台配置不太高的PC可
  • qt界面之toolTip

    一般需要在按钮中加入toolTip的提示 可以如下所示 后续继续更新
  • java并发编程

    并发编程 1 java线程 1 1 创建线程 1 1 1 Thread 匿名内部类实现Thread线程 new Thread t1 Override public void run start 1 1 2 Runnable new Thre
  • MobaXterm 终端永久设置字体大小

    刚接触 MobaXterm 没多久 想设置下界面字体大小 结果翻了翻网上 一些人都在瞎扯 没一个好用的 自己解决之后 特写出来 找到顶部的Settings 进去之后 找到font settings 调整为你想要的字体大小 一般12 14 就
  • 听老人一句劝,别去外包,干了四年,废了....

    我是一个普通二本大学机械专业毕业 目前做IT行业的软件测试已经有4年多了 18年通过校招进入湖南某软件公司 干了接近4年的功能测试 今年年初 感觉自己不能够在这样下去了 长时间呆在一个舒适的环境会让一个人堕落 而我已经在一个企业干了四年的功
  • QT笔记——信号与槽

    Qt信号与槽机制通过connect 关联信号 QT4 1 槽函数必须有slots关键字 2 SIGNAL SLOT 将函数转为字符串 不进行错误检查 3 槽函数和信号一致 参数 返回值 没有返回值 sender 发送信号的对象 signal
  • C++中在类中重载输出运算符时遇到error: declaration of ‘class T‘的问题的解决

    一 问题代码及报错提示 include