当前位置: 首页 > news >正文

开发中ostringstream,格式化输出的问题

模板函数-toStr函数的解释

std::string toStr(const T& value) {std::ostringstream ostr;// 如果是浮点类型,设置固定格式和精度if constexpr (std::is_floating_point_v<T>) {ostr << std::fixed << std::setprecision(4);  // 固定四位小数}ostr << value;return ostr.str();}
的工作原理,如何生效的?

这段代码的工作原理可以分为以下几个部分进行解释,它结合了模板编程std::ostringstream 的功能、if constexpr 语法以及 type_traits 特性来实现对浮点类型和非浮点类型的不同处理。以下是具体工作原理的分解:

1. 模板函数的通用性

template<typename T>
std::string toStr(const T& value) {// ...
}

这是一个模板函数,意味着它可以接受任意类型 T 作为参数。当你调用 toStr(value) 时,编译器会根据传入的参数类型推导出 T 的实际类型。例如:

  • 如果传入的是 int 类型,编译器会实例化 Tint,生成一个针对 int 类型的 toStr 函数。
  • 如果传入的是 double 类型,编译器会实例化 Tdouble,生成一个针对 double 类型的 toStr 函数。

模板的这一特性使得它具有高度的通用性,可以处理任意数据类型。

2. std::ostringstream 的作用

std::ostringstream ostr;

std::ostringstream 是标准库中的字符串流,它是 std::ostream 的派生类。它允许像操作文件流、控制台输出流那样,将数据输出到内存中的字符串流中。使用 << 操作符,数据将被插入到流中。

例如:

ostr << value;

这行代码会将 value 的内容以字符串的形式插入到 ostr 中。ostringstream 处理了标准的数据类型,并将其转换为文本形式,存储在流缓冲区内。

最后,通过调用 ostr.str(),可以获取该流的内容并返回为 std::string,从而实现将不同类型的数据转换为字符串。

3. if constexpr 的静态编译期检查

if constexpr (std::is_floating_point_v<T>) {ostr << std::fixed << std::setprecision(4);  // 固定四位小数
}
什么是 if constexpr

if constexpr 是 C++17 引入的特性,它和普通的 if 不同,if constexpr 会在编译时进行条件检查。如果条件为 true,对应的代码块将被编译;如果为 false,对应的代码块则会被忽略,不会被编译。这在模板编程中非常有用,因为我们可以根据模板参数的不同类型生成不同的代码,而不需要在运行时判断类型。

在这段代码中,std::is_floating_point_v<T> 是一个类型特性(来自 <type_traits> 头文件),它用于检查 T 是否为浮点类型(float, double, long double)。如果 T 是浮点类型(如 float, double),则 std::is_floating_point_v<T> 会返回 true,编译器将包含 ostr << std::fixed << std::setprecision(4); 这段代码,并在将浮点数插入流时,强制保留固定的4位小数。

作用:
  • std::fixed:强制以固定点数格式输出浮点数,防止使用科学计数法。
  • std::setprecision(4):设定浮点数的小数点后的精度为 4 位。

因此,当你传递一个浮点数时,比如 3.14159265,输出将是 3.1416,保留4位小数。

如果 T 不是浮点类型,if constexpr 的条件为 false,编译器将直接忽略这个分支中的代码,流将按默认行为进行输出。

4. 默认的插入操作

ostr << value;

无论传入的是哪种类型,最终都会执行这条语句,将 value 插入到 ostr 流中。这依赖于 << 操作符的重载机制。如果 T 是整数类型、字符串类型等,都会按默认的格式直接插入流中。这个插入操作会根据 T 的类型不同,调用适当的 << 重载函数。

5. 返回字符串

return ostr.str();

ostr.str() 会返回流缓冲区中的字符串内容,即最终拼接好的结果。无论插入的值是 intdouble 还是 float,此时已经被格式化为字符串,返回值类型为 std::string

代码生效的流程

  • 步骤1: 当调用 toStr(3.14159) 时,编译器推导出 Tdouble 类型,编译器实例化出一个 TdoubletoStr 函数。
  • 步骤2: if constexpr 判断 std::is_floating_point_v<double>true

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 7.测试用例设计方法 + Bug
  • 系统性能分析工具sysstat之sar命令以及nginx中打开gzip使用配置gzip_http_version值为1.0和1.1时遇到的结果乱码问题
  • 创游系列开心娱乐完整组件
  • Gmtracker_深度学习驱动的图匹配多目标跟踪项目启动与算法流程
  • 解锁精准电商营销新纪元:深度剖析京东商品详情API数据驱动的营销策略
  • 2024.9.10
  • STL02——手写简单版本的list
  • 中介者模式mediator
  • 参赛心得和思路分享:2021第二届云原生编程挑战赛2: 实现一个柔性集群调度机制
  • linux ubuntu编译 openjdk11
  • ## 1.3.Git命令
  • 【网络安全】-xss跨站脚本攻击-pikachu
  • Python 全局变量使用指南
  • 【人工智能】大模型重要概念
  • Django 模型索引的创建
  • 002-读书笔记-JavaScript高级程序设计 在HTML中使用JavaScript
  • Android Studio:GIT提交项目到远程仓库
  • CEF与代理
  • crontab执行失败的多种原因
  • ESLint简单操作
  • javascript 总结(常用工具类的封装)
  • Koa2 之文件上传下载
  • Linux各目录及每个目录的详细介绍
  • Linux学习笔记6-使用fdisk进行磁盘管理
  • PhantomJS 安装
  • Vue2.0 实现互斥
  • vue从创建到完整的饿了么(11)组件的使用(svg图标及watch的简单使用)
  • 程序员该如何有效的找工作?
  • 订阅Forge Viewer所有的事件
  • 前端之Sass/Scss实战笔记
  • 驱动程序原理
  • 运行时添加log4j2的appender
  • 责任链模式的两种实现
  • MPAndroidChart 教程:Y轴 YAxis
  • MyCAT水平分库
  • Spring第一个helloWorld
  • 资深实践篇 | 基于Kubernetes 1.61的Kubernetes Scheduler 调度详解 ...
  • ​十个常见的 Python 脚本 (详细介绍 + 代码举例)
  • # centos7下FFmpeg环境部署记录
  • # Panda3d 碰撞检测系统介绍
  • #NOIP 2014# day.1 T2 联合权值
  • #QT(QCharts绘制曲线)
  • #前后端分离# 头条发布系统
  • $NOIp2018$劝退记
  • (3)STL算法之搜索
  • (70min)字节暑假实习二面(已挂)
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (LNMP) How To Install Linux, nginx, MySQL, PHP
  • (附源码)ssm跨平台教学系统 毕业设计 280843
  • (规划)24届春招和25届暑假实习路线准备规划
  • (函数)颠倒字符串顺序(C语言)
  • (数据结构)顺序表的定义
  • (五)大数据实战——使用模板虚拟机实现hadoop集群虚拟机克隆及网络相关配置
  • (轉貼) VS2005 快捷键 (初級) (.NET) (Visual Studio)
  • .apk文件,IIS不支持下载解决