关于C++模板类运算符重载在类内外实现的不同

类模板中使用重载输出运算符<< VS2019编译器提示无法解析的外部命令 类模板中使用重载输出运算符<< VS2019编译器提示无法解析的外部命令   在模板类, 使用重载运算符的时候,编译器无法通过编译   后来问了群里大牛, 才知道是C++开发者挖的一个坑, 只要在代码里添加<>就完美解决   代码: #pragma once #include <iostream> using namespace std; //Vector容器类 template <typename T> class Vec 阅读详情

最近在学习c++的模板,起初还挺顺利,但是在模板类遇到了一个IO流重载的问题

首先我是这样写的,但是不能编译

#include<iostream>
using namespace std;
template<typename T>
class A
{
    private:
        T c;
    public:
        A(){}
        friend ostream& operator<<(ostream& os, const A &a);
        friend istream& operator>>(istream& is, A &a);
};
istream & operator>>(istream& is, A& a) //问题出在这里 编译器提示我
{                                       //缺少 类模板 "A" 的参数列表 ostream 同理
    is >> a.c;
    return is;
}
ostream & operator<<(ostream& os, const A& a)
{
    os << "a: " << a.c << endl;
    return os;
}
int main()
{
    A<int> a;
    cin >> a;
    cout << a;
}

按照编译器的提示 我一步一步改成了这样

template<typename T>                              // 1
istream & operator>>(istream& is, A<T>& a)        //2
{
    is >> a.c;
    return is;
}
template<typename T>                            //3
ostream & operator<<(ostream& os, const A<T>& a)//4
{
    os << "a: " << a.c << endl;
    return os;
}

改了四处地方,编译器不给你看波浪线了,但是还是不能运行,编译运行编译器会给你这样报错

Undefined symbols for architecture x86_64:
“operator<<(std::__1::basic_ostream<char, std::__1::char_traits >&, A const&)”, referenced from:
_main in test-0193fd.o
“operator>>(std::__1::basic_istream<char, std::__1::char_traits >&, A&)”, referenced from:
_main in test-0193fd.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

**

但是,我把函数放在类内部实现

**

#include<iostream>
using namespace std;
template<typename T>
class A
{
    private:
        T c;
    public:
        A(){}
        friend ostream& operator<<(ostream& os, const A<T> &a)
        {
            os << "a: " << a.c << endl;
            return os;
        }
        friend istream& operator>>(istream& is, A<T> &a)
        {
            is >> a.c;
            return is;
        }
};
int main()
{
    A<int> a;
    cin >> a;
    cout << a;
}

然后我发现了一个BUG

#include<iostream>
using namespace std;
template<typename T>
class A
{
    private:
        T c;
    public:
        A(){}
        friend ostream& operator<<(ostream& os, const A &a) // 这里删掉了<T>
        {
            os << "a: " << a.c << endl;
            return os;
        }
        friend istream& operator>>(istream& is, A &a)  // 这里也是
        {
            is >> a.c;
            return is;
        }
};
int main()
{
    A<int> a;
    cin >> a;
    cout << a;
}

发现这样还是可以正常run,总是感觉不对劲,然后我去翻了一下《C++ Primer Plus》书上明确说明这样写是非法的,因为不存在A这样的对象必须要带上< T > 才合法。

最后说一下如何在类外实现IO流重载

找了好多篇博客发现都没有在类外实现IO流重载
有一篇博客解决了这个问题,作者的思路还是比较奇特,不过确实是解决了问题,给大家参考一下
网上搜到的一种解决方法
但是比较麻烦,我们可以有更简便的方法来实现


#include<iostream>
using namespace std;
template<typename T> class A;                           //前置声明
template <typename T> ostream & operator<<(ostream &os, const A<T> &a); 
template <typename T> istream & operator>>(istream &is, A<T> & a); 

template<typename T>
class A
{
    private:
        T c;
    public:
        A(){}
        friend istream& operator>> <T>(istream& is, A<T> &a);  
        // 这里要加一个<T>
        friend ostream& operator<< <T>(ostream& os, const A<T> &a); 
        //注意用空格将 <<与<T>隔开
};

template<typename T>                              
istream & operator>> (istream& is, A<T>& a)       
{
    is >> a.c;
    return is;
}
template<typename T>                            
ostream & operator<< (ostream& os, const A<T>& a)
{
    os << "a: " << a.c << endl;
    return os;
}

int main()
{
    A<int> a;
    cin >> a;
    cout << a;
}

这样就完美地在类外实现了IO流重载

所有代码都是在Mac下用vscode进行测试,但是经过我使用其他编译器,以及在Windows下测试所得结果一致,应该不会有太大差别。

C++中模板类的友元重载 一个由《程序员面试宝典》引出的问题。 描述模板类的友元重载,用C++代码实现? 这实际上考察的是下面几个问题: 1.模板类的编写 2.模板类中友元函数的编写 3.什么时候会用到友元重载?答案是各种C++中的运算符。最典型的就是输出操作符 书上给出的答案如下: #include using namespace std; template class Test; template 阅读详情

相关推荐

模板类的友元函数、重载运算符、转换函数

#ifndef IPANDA_H #define IPANDA_H // 不能将模板成员函数放在单独的实现文件, // 因为模板不是函数,不能单独编译 #include <string> #include <iostream> // 模板类的约束模板友元函数,因为友元函数是模板函数, // 所以此处是友元函数的模板函数的声明,并且要在模板类之前声明, // 所以是<t...

ipanda_zll的博客 644

模板类中重载<<和>>操作符

转:模板类中重载>操作符 模板类中操作符重载问题(">"重载) 在模板类中输入流“>>”和输出流“>"的重载。 一、将输出流">"重载的实现写在类中 #include "stdafx.h" #include    using   namespace   std;       templateclass T>   class Test   {      pu

a simplicity of zone 1453

STM32H743 ADC校准失败排查:HAL_ADCEx_Calibration_Start()的正确调用时机

本文深入剖析了STM32H743 ADC校准失败的核心原因,即错误地在ADC使能状态下调用HAL_ADCEx_Calibration_Start()函数,导致读数漂移。文章详细解释了校准必须在ADC禁用状态下进行的硬件原理,列举了典型错误场景,并提供了上电初始化与周期性重校准的正确代码实践,帮助开发者彻底解决ADC精度问题。

ik678901的博客 1175

C++ 类内重载输出运算符、类外重载输出运算符的区别;及其调用区别;operator<<

目录前言一、类内与类外重载运算符1.类内重载与类外重载的区别2.类外重载为什么需要友元关于模板类3.类内重载与类外重载,调用的区别二、实例实现效果:参考 前言 最后的实例利用一个模板类来实现类内与类外重载输出运算符。 其他运算符的重载类似。 如果不需要模板,去掉模板即可。 一、类内与类外重载运算符 1.类内重载与类外重载的区别 1.1类外重载一般需要类内声明友元,详见2. 1.2类内实现,调用的时候需要用对象调用,参数列表只包含一个ostream类引用。 1.3类内,作为成员函数,所以没有友元声明一说。

多丰富下自己呀 2799

双向可控硅控制后续篇:过零检测电路、丢波、斩波、定时

双向可控硅功率控制技巧,掌握AC负载的控温控速等。

qq_42289734的博客 3万+

EFR32无线SoC开发指南:从环境搭建到性能优化

物联网边缘设备开发中,无线SoC芯片的选择与开发环境配置是关键第一步。EFR32作为Silicon Labs推出的多协议无线SoC系列,配合Simplicity Studio IDE,为开发者提供了完整的解决方案。本文以EFR32xG22开发套件为例,详细介绍开发环境搭建、工程创建、硬件配置等核心环节,特别针对RAILtest示例工程进行深入解析。通过实际案例演示如何配置无线参数、优化低功耗模式,并分享串口终端交互、吞吐量测试等实战技巧。对于开发者常见的问题如设备识别失败、无线通信异常等,提供了系统化的排查

weixin_30342363的博客 350

【C++】运算符重载 ② ( 类内部定义云算符重载 - 成员函数 | 类外部定义运算符重载 - 全局函数 | 可重载的运算符 )

一、运算符重载本质 二、运算符重载语法 - 类内部定义云算符重载 ( 成员函数 ) 1、运算符重载函数语法说明 2、运算符重载函数调用 3、代码示例 - 运算符重载函数调用 三、运算符重载语法 - 类外部定义运算符重载 ( 全局函数 ) 1、运算符重载函数语法说明 2、运算符重载函数调用 四、可重载的运算符

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 939

CloudCompare 二次开发(9)——半径滤波

基于PCL对CloudCompare软件进行二次开发,实现的算法功能是半径滤波

点云侠的博客 1399

Coursera 学习记录:类和对象基础#1(自定义构函数以及“函数的返回值是引用”)

描述 下面程序输出的结果是: 0 5 #include &lt;iostream&gt; using namespace std; class A { public: int val; // 在此处补充你的代码 }; main() { A a; cout &lt;&lt; a.val &lt;&lt; endl; a.GetObj() = 5; cout &lt;&lt; a.val &lt...

AhaKnow 481

Windows远程桌面开发之九-虚拟显示器(Windows 10 Indirect Display 虚拟显示器驱动开发)

by fanxiushu 2019-06-24 转载或引用请注明原始作者。 这里与远程桌面关系不是太大,但这个部分是xdisp_virt远程控制程序的实现多显示器桌面扩展的子功能,因此也归为远程桌面开发一类。 这篇文章与之前发布的...

fanxiushu的专栏 2万+

通信原理 | 通俗理解 | 因子图、消息传递以及它们之间的关系

在算法迭代过程中,通过反复更新这些消息,直到收敛,最终可以得到每个变量的边缘概率分布或最有可能的整体状态。算法通过因子图中的节点反复交换消息,直到找到最优解或所有消息稳定下来,从而解决了比如聚会日期这样的优化问题。在实际应用中,这种方法可以用来解决更复杂的问题,比如图像识别、语音识别和机器学习中的其他问题。,特别是在处理概率模型和执行概率推断时,因子图提供了一个强大的工具。(比如朋友的空闲时间和地点的可用性),并且你希望尽可能让所有人满意。在真正的因子图和消息传递算法中,这个过程被数学化和形式化。

若北辰 1191

C++重载->运算符

为了这样做,它使用了 `const_cast` 去掉 `const` 限制,并调用非 `const` 版本的 `operator->()`。- `const_cast(*this)` 将 `*this` 转换为非 `const` 类型,以便调用非 `const` 版本的 `operator->()`。- 使用 `const_cast` 将 `*this` 转换为非 `const`,然后委托给非 `const` 重载版本。这两个 `->` 运算符的重载写法是**正确的**,没有问题。

henry747647的专栏 1859

【YOLO系列】YOLOv11详解:模型结构、损失函数、训练方法及代码实现

YOLOv11在目标检测领域实现重大突破,通过动态骨干网络(Dyna-Backbone)和FPN++架构,在保持高帧率(≥60FPS)的同时提升小目标检测精度(AP_S提升5.6%)。创新采用CIoU++损失函数和类别平衡Focal Loss,结合Mosaic-Plus数据增强,参数量减少18%至6.5M。实验显示,该模型在COCO数据集上实现更高mAP,特别适合移动端部署,Jetson Xavier平台能耗比优化至3.2W·ms⁻¹,支持目标检测、实例分割等多任务场景。关键创新包括动态深度调整和双向特征金

一碗白开水一 3443

C++模板类的运算符重载

有关模板类的流插入运算符重载问题

LeBrother的博客 4366

【漏洞复现】永恒之蓝 MS17-010 远程溢出漏洞(CVE-2017-0143)

文章目录声明前言一、漏洞原理简述二、漏洞代码深层解析三、实验步骤四、漏洞补丁总结 声明 本篇文章仅用于技术研究与技术学习,切勿用于非授权下攻击行为,切记! 前言 Windows7 存在 MS17-010 永恒之蓝(远程溢出漏洞) ,该漏洞是方程式组织在其漏洞利用框架中一个针对SMB服务进行攻击的漏洞,该漏洞导致攻击者在目标系统上可以执行任意代码 一、漏洞原理简述 MS17-010漏洞出现在Windows SMB v1中的内核态函数 srv!SrvOs2FeaListToNt 在处理FEA(File Ex

李同學AI安全 9627

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

关于C++运算符的重载

C++运算符的重载,为C++提供了可扩展性,这也是C++最吸引人的属性之一。在完成同样的操作的情况下,如果运算符重载能够比用明确的函数调用使程序更清晰,则应该使用运算符的重载。从本质上讲,我始终认为运算符的重载本身也是类的一个成员函数,只不过这个成员函数的写法不可以按照自己的意愿随意的起名字,要按照C++语法规范来写,不过就运算符本身的实现来看,似乎真的和函数没有什么两样。关于C++运算符

天下有雪 6228

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

C++类模板 实现运算符重载

#include<iostream> using namespace std; template<class T> class A { private: T value; public: A(){this->value=0;} A(T value) { this->value=value; } ~A...

weixin_39644095的博客 2214

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

05模板学习之模板类外实现重载运算符和友元函数

05模板学习之模板类外实现重载运算符和友元函数 注意1: 本文中说的类外是指在单文件的.cpp中实现模板的运算符重载和友元函数,不包含.h文件。 注意2: 本测试项目在main.cpp中测试,即是一个单文件,模板的单文件和.h、.cpp是有区别的,与平常的普通分离.h,.cpp不一样。 1 友元函数在类模板的写法 //方法2-友元函数在类模板的声明 template<class T> class Person; template<class T> void PrintPerson(P

weixin_44517656的博客 817

C++运算符重载总结

@著作权归作者所有:来自优快云博客作者大胡子的艾娃的原创作品,如需转载,请注明出处https://blog.youkuaiyun.com/qq_43148810,否则将追究法律责任。 如有错误的地方欢迎指正,谢谢! 更多内容请关注个人博客:https://blog.youkuaiyun.com/qq_43148810 ...

qq_43148810的博客 4055

关于c++模板类<<运算符的重载方法

关于模版函数运算符重载的问题

weixin_48336920的博客 1055

【C++】泛型编程 ⑪ ( 类模板的运算符重载 - 函数实现 写在类外部的不同的 .h 头文件和 .cpp 代码中 )

一、类模板的运算符重载 - 函数实现 写在类外部的不同的 .h 头文件和 .cpp 代码中 1、分离代码 后的 友元函数报错信息 - 错误示例 Student.h 头文件内容 Student.cpp 代码文件内容 Test.cpp 代码文件内容 执行报错信息 2、问题分析 二、代码示例 - 函数实现 写在类外部的不同的 .h 头文件和 .cpp 代码中 1、完整代码示例 Student.h 头文件内容 Student.cpp 代码文件内容 Test.cpp 代码文件内容 2、执行结果

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 1008

C++模板类的使用以及运算符重载的实现

一、类模板及运算符重载的实现 如同函数模板一样,使用类模板使用户可以为类定义一种模式,使得类中的某些数据成员、某些成员函数的参数、某些成员函数的返回值能取任意类型。类模板是对一批仅仅成员数据类型不同的类的抽象,程序员只要为这一批类所组成的整个类家族创建一个类模板,给出一套程序代码,就可以用来生成多种具体的类,(这类可以看作是类模板的实例),从而大大提高编程的效率。 定义类模板的一般形式是...

xhj_enen的博客 1万+

C++(3):运算符重载 && 模板函数和模板类

一、运算符重载 1.运算符的重载:实际是一种特殊的函数重载,必须定义一个函数,并告诉C++编译器,当遇到该重载的运算符时调用此函数。这个函数叫做运算符重载函数,通常为类的成员函数。 定义运算符重载函数的一般格式: 返回值类型 类名::operator重载的运算符(参数表) {……} operator是关键字,它与重载的运算符一起构成函数名。 Int Int ::...

kimEHEH的博客 1636

用string实现的一个完整的类,包含以下操作:重载运算符 > >,< < ,string模板类,fstream对二进制数据读写

///// 一个完整的类,包含以下操作:重载运算符 >,赋值转换,string模板类,fstream对二进制数据读写#include #include #include using namespace std;class Tperson;          // declaration of Tperson classostream& operator // declaration o

Peter的专栏 2985

c++ 实现Set模板类,并重载+、-<<和>>操作符;

实现集合set模板类,实现添加,删除,查找,并实现重载交*,并+,差-集运算符的重载

m0_73692754的博客 1992

【C++ | bug | 运算符重载】定义矩阵(模板)类时,使用 “友元函数” 进行 * 运算符重载时编译报错

【C++ | bug | 运算符重载】关于定义矩阵(模板)类时,使用 “友元函数” 进行 * 运算符重载时编译报错——一种可能的解决方案。

你的问题在于,读书太少而想得太多。 1602
上一篇: codeforce 999E(连通图问题)
下一篇: 动态规划——斜率优化
Linda_yezi_coder
博客等级 码龄7年 20粉丝 88原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值