关于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

NLP自然语言处理:神经网络语言模型(NNLM)

目录 一、传统语言模型 1.1 稀疏性 1.2泛化能力差 二、神经网络语言模型 2.1 前馈神经网络模型(FFLM) 2.2 循环神经网络模型(RNNLM) 2.2.1循环神经网络模型示例 2.2.2RNN语言模型训练过程 2.2.3RNN语言模型反向传播 2.2.4语言模型评估 语言模型的构建目的是为了对语言中的各要素的分布进行估计,具有较长的研究历史和广泛...

陈宸的博客 1万+

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

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

多丰富下自己呀 2799

Ansys-结构动力学分析-圆柱斜齿轮模态分析学习心得

模态分析的步骤基本一直,不同点在于选择什么单元类型,模型,节点约束等 圆柱斜齿轮模态分析的难点在于圆柱斜齿轮的模型建立,和所要约束的节点的选择。 用命令流方法建立齿轮模型效率较高,当然,在ansys里建立复杂的模型实在不敢恭维,对于自下而上建模,需要知道每个关键点的坐标位置。下图是创建圆柱斜齿轮模型的命令流方式。 模型不同使用的数据也就不同了。 对于施加约束的问题这就必须要熟悉select e...

weixin_45385183的博客 1831

两层板如何做阻抗控制呢

两层板如何做阻抗控制呢? 这个问题可能很多人都会碰到,有的人在此等需要做阻抗控制的情况都选择做多层板。诚然,多层板在阻抗控制,EMC等等方面都有着天然的优势。然而,在价格上和周期上,两层板就有着绝对优势了。 对于成本非常敏感而又不是太复杂的产品,尽管对于我们硬件工程师而言,有一堆的理由要求使用多层板。然而在面对毛都不懂的老板“别人能做,你为什么不能做?”这个问题时只得低下我们高傲的头颅。 好...

weixin_42005993的博客 2万+

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

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

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

白话详细解读(七)----- CBAM:Convolutional Block Attention Module

一、CBAM简介 论文链接:https://x.sci-hub.org.cn/scholar?hl=zh-TW&as_sdt=0%2C5&q=CBAM%3A+Convolutional+Block+Attention+Module&btnG=&oq=CB CBAM这篇论文是在2018年提出的,自提出之后,已经被引用上千次,可见其影响力。CBAM是一种专门为了卷积神经网络而设计的注意力模块,传统的卷积存在只关注局部信息,而往往忽略全局信息的弊端,以3*3卷积为例,滤波器有9个

奋斗の博客 1万+

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

基于Codex与Skills的学术研究自动化全流程实战指南

还在为海量文献下载、整理、阅读和综述写作而头疼吗?面对堆积如山的PDF,你是否感到无从下手?从选题、文献检索、到写作、绘图、润色,再到应对AI检测和审稿意见,学术研究的每一步都充满挑战。本文将为你带来一套堪称“王炸组合”的解决方案: Codex + Skills 。这不是简单的工具介绍,而是一套从零开始,覆盖学术研究全流程的保姆级实战教程。我们将手把手教你如何安装、配置,并利用强大的Skills(技能)自动化处理文献下载管理、高效撰写综述、生成专业图表、智能润色降重,直至应对审稿。无论你是科研新手还是希望提

weixin_29041195的博客 761

把群晖NAS变成游戏开发服务器:Perforce与虚幻引擎深度整合的5个关键配置(含.p4ignore模板)

本文详细介绍了如何将群晖NAS配置为游戏开发服务器,重点讲解了Perforce与虚幻引擎的深度整合。通过五个关键配置节点,包括用户权限架构、Workspace策略、资产同步优化、仓库清洁度保障和编辑器深度集成,帮助小型团队打造高效开发环境。文章还提供了实用的.p4ignore模板和优化技巧,显著提升开发效率。

weixin_30430677的博客 317

C++重载->运算符

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

henry747647的专栏 1859

Nacos启动报错No DataSource set?5分钟搞定standalone模式配置

本文针对Nacos启动时常见的“No DataSource set”报错,深入解析了其根源在于默认集群模式与外部数据库依赖。提供了两种快速解决方案:通过命令行参数“-m standalone”启动,或直接修改启动脚本配置文件,从而在5分钟内以单机模式成功启动Nacos,无需配置MySQL数据库。

weixin_29234509的博客 465

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

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

LeBrother的博客 4366

【第1章>第5节】SOM自组织映射网络的理论学习与MATLAB仿真

自组织映射网络(Self-Organizing Map,SOM)是一种无监督学习的人工神经网络,由芬兰学者Teuvo Kohonen于1981年提出,也被称为Kohonen网络。它的主要功能是将高维输入数据映射到低维(通常是二维)的离散网格上,同时保持输入数据的拓扑结构,即相邻的输入数据在映射后的网格上也相邻。

FPGA/MATLAB学习教程/源码/项目合作开发 401

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

关于C++运算符的重载

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

天下有雪 6228

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

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

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

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

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

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、付费专栏及课程。

余额充值