百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程网 > 正文

C++ 为path类专门化std::formatter

yuyutoo 2024-10-18 12:16 2 浏览 0 评论


path类在文件系统库中被用来表示文件或目录路径。在POSIX兼容系统(如macOS和Linux)上,path对象使用char类型来表示文件名。在Windows上,path使用wchar_t。在Windows上,cout和format()不会显示wchar_t字符的原始字符串。这意味着没有简单的即用型方法来编写跨POSIX和Windows的可移植代码,这些代码使用了文件系统库。

我们可以使用预处理器指令为Windows编写特定的代码版本。对于某些代码库来说,这可能是一个合理的解决方案,但对于本书来说,这样做既混乱又不符合简单、可移植、可重用示例的目的。

优雅的解决方案是为path类编写一个C++20 formatter专门化。这允许我们以简单和可移植的方式显示path对象。

如何做……

在本示例中,我们将为fs::path类编写一个formatter专门化:

首先,为了方便起见,我们使用一个命名空间别名。所有文件系统名称都在std::filesystem命名空间中:

namespace fs = std::filesystem;


我们为path类编写的formatter专门化简单且简洁:

template<>  
struct std::formatter<fs::path>: std::formatter<std::string> {  
    template<typename FormatContext>  
    auto format(const fs::path& p, FormatContext& ctx) {  
        return format_to(ctx.out(), "{}", p.string());  
    }  
};


在这里,我们为fs::path类型专门化了formatter,使用其string()方法来获取可打印的表示形式。我们不能使用c_str()方法,因为它在Windows上与wchar_t字符不兼容。

本书中第1章“新的C++20特性”中有对formatter专门化的更完整解释。

在main()函数中,我们使用命令行传递文件名或路径:

int main(const int argc, const char** argv) {  
    // ... 省略了检查参数数量的代码 ...  
  
    fs::path dir{ argv[1] };  
  
    if(!fs::exists(dir)) {  
        cout << format("path: {} does not exist\n", dir);  
        return 1;  
    }  
  
    cout << format("path: {}\n", dir);  
    cout << format("filename: {}\n", dir.filename());  
    cout << format("cannonical: {}\n", fs::canonical(dir));  
}


argc和argv参数是标准的命令行参数。

argv[0]始终是可执行文件本身的完整目录路径和文件名。如果我们没有正确数量的参数,我们将显示argv[0]的文件名部分作为用法消息的一部分。

在这个示例中,我们使用了一些文件系统函数:

- fs::exists()函数检查目录或文件是否存在。

- dir是一个path对象。我们现在可以直接将它传递给format(),使用我们的专门化来显示路径的字符串表示形式。

- filename()方法返回一个新的path对象,我们直接将其传递给format(),使用我们的专门化。

- fs::canonical()函数接受一个path对象,并返回一个新的path对象,其中包含规范的绝对目录路径。我们将此path对象直接传递给format(),它显示从canonical()返回的目录路径。

输出示例:

$ ./formatter ./formatter.cpp  
path: ./formatter.cpp  
filename: formatter.cpp  
cannonical: /home/billw/working/chap10/formatter.cpp


它是如何工作的……

fs::path类在文件系统库中被用来表示目录路径和文件名。通过提供formatter专门化,我们可以轻松地在不同平台上一致地显示path对象。

path类提供了一些有用的方法。我们可以遍历一个路径来查看其组成部分:

fs::path p{ "~/include/bwprint.h" };  
cout << format("{}\n", p);  
for(auto& x : p) cout << format("[{}] ", x);  
cout << '\n';


迭代器返回路径中每个元素的path对象。

我们还可以获取路径的不同部分:

fs::path p{ "~/include/bwprint.h" };  
cout << format("{}\n", p);  
cout << format("{}\n", p.stem());  
cout << format("{}\n", p.extension());  
cout << format("{}\n", p.filename());  
cout << format("{}\n", p.parent_path());


在本章中,我们将继续使用这个为path类编写的formatter专门化。

相关推荐

高一高二第一次月考认真作答(高二第一次月考的重要性)

正在进行高一、高二第一次月考,同学们正在认真完成化学试卷,研究考纲,探究考点,夯实基础,迎战高考!

山清水秀,盛世今朝(山清水秀出处)

万千星河,神州妖娆!山清水秀,盛世今朝!龙腾虎跃,锦绣前程!千里婵娟,祝福永远!

我校二模成绩已新鲜出炉(二模考试成绩)

充电加油备战高考,积极努力再拼一搏...

Argon Design向瑞萨电子有限公司提供Argon Streams VP9许可证

英国剑桥--(美国商业资讯)--领先的先进视频验证解决方案提供商ArgonDesignLtd已与日本半导体公司瑞萨电子有限公司(RenesasElectronicsCorporation)签署...

高考倒计时75天(高考倒计时75天励志语)

今天是2022年3月24日星期四,距离2022年高考还有75天时间对于十八岁的高三学子来说,有些事情的确会影响你们的一生,但是没有一件事能决定你们的一生!努力的意义,就是:以后的日子里,放眼望去,全...

期中考试正在进行(期中考试在即)

转眼即瞬,期中考试已到,紧张忙碌的两个月学习,检验的时刻到了。让我们拿出信心和勇气,来挑战自我。面对考验,我们该做的就是沉着,冷静。让知识来一次次洗礼我们的灵魂,让失败和成功迎接一次次的成长。你们可以...

不要浪费了你NAS上的HDMI接口!详解华硕NAS上HDMI接口的妙用

不要浪费了你NAS上的HDMI接口!详解华硕NAS上HDMI接口的妙用之前我在本站分享我使用的华硕(ASUS)AS6704T...

Java通过Kafka Streams库来实现数据流处理

#暑期创作大赛#...

From abandoned mines to limpid streams waters: how banks profit from EOD

ByZENGYanglinInthecurrentpursuitofthe“dualcarbon”target(carbonpeakingandcarbonneutra...

SPSS与Streams的集成实现实时预测

SPSSModeler是一个数据挖掘工作台,提供了一个可了解数据并生成预测模型的最先进的环境。Streams提供了一个可伸缩的高性能环境,对不断变化的数据进行实时分析,这些数据中包括传统结构的数据...

Kafka Streams, 我还会再使用它吗?

DeeptiMittal4分钟阅读...

大数据Hadoop之——Kafka Streams原理介绍与简单应用示例

一、KafkaStreams概述官网文档:https://kafka.apache.org/32/documentation/streams/...

Android上的TCP今天开始向用户推出,并将在下个月向所有用户提供

据extends网3月15日报道,Firefox今天宣布,其保护用户免受跟踪器攻击的全面cookie保护(TCP)功能现已在Android上可用。该功能默认启动模式,这样,跟踪器将无法收集有关用户的浏...

Linux curl命令(linux curl命令安装)

Linuxcurl命令是一个利用URL规则在命令行下工作的文件传输工具。它支持文件的上传和下载,所以是综合传输工具,但按传统,习惯称curl为下载工具。作为一款强力工具,curl支持包括HTTP、H...

go语言http服务入门详解(go语言http服务器)

当你在浏览器中输入URL时,实际上是在发送一个对Web页面的请求。该请求被发送到服务器。服务器的工作是获取适当的页面并将其作为响应发送回浏览器。在Web的早期,服务器通常读取服务器硬盘上HTML文件的...

取消回复欢迎 发表评论: