再再再补充一个重载决议的例子。 大家可能在某些地方见过 ::std:: 这样的代码,比如 ::std::swap,::std::vector,::std::nullptr_t。 在 Qualified Name Lookup 一节的子节 Namespace Member Lookup 已经介绍,名称前面以 :: 修饰表示在全局作用域下查找。 一个例子: namespace A { namespace B { void f() { std::cout << "A::B::f()\n"; } } } namespace B { void f() { std::cout << "B::f()\n"; } } namespace A { void h() { ::B::f();… Continue Reading std:: versus ::std::

霜风凄紧,神寒骨冷,忽忽冬月将尽。忙处更新渐少,今来补上。 本篇讲解如何利用 ChatGPT 快速实现一个控制台进度条小工具,相比单纯介绍某些特性,此种方式涉及知识的综合运用,也顺便谈谈如何结合 AI 进行编程。 问题描述 控制台程序执行一些耗时任务时,需要向用户显示当前任务执行的进度,以提供清晰的感知。比如一个下载程序,通过进度条便能告知用户当前的下载进度。 进度条可以单独显示,也可以在程序输出的最下方显示,下图是一个示例。 这是一种单控制条需求,执行任务,显示进度,输出流依旧是从上至下依序进行,适合单线程的场景。 多控制条显示的效果如下图,实现要更加复杂一些,本文暂时不会涉及该部分。 初步分析 控制台上显示的这种符号,称为 ASCII Art,就是以字符构建的某种图案,不借助图片,也能够有一个生动的展示效果,比如下图这种。 因此控制台进度条也称为 ASCII Progress Bar,通过字符图案来模拟进度条的显示,通常分为已完成部分及未完成部分,使用两个字符,动态改变字符数量,便能够模拟出一个进度条。 模拟方式既定,下一问题在于进度条刷新。如果每更新一次进度,便输出一个字符图案,那么屏幕上将满是进度条,需要针对一条进度条,不断刷新其数据,而非每次都输出一条新的。具体实现时,便需要寻找定位进度条的方法,每次清除当前数据,重新打印新的数据,视觉上显示的是连续动画。 刷新思路亦成,接着的问题在于如何在进度条之上插入其他输出。进度条始终显示在用户输出下方,因此每次用户输出时,可以立即定位到进度条,定位之后清除当前进度条,输出用户内容,再重新打印进度条,便能够达到这一效果。 细枝末节,便需依赖具体的实现手法。 借助 ChatGPT 快速构建基本代码 需求明确,思路既定,接着便要着手设计库的结构和细节,实现细节这部分代码无需从零编写,可以借助 AI 快速生成。 我们所需做的,就是详细描述需求,以及预想的思路,让 ChatGPT 生成代码,验证是否符合需求,若不符合,纠正错误,让它再次生成,不断重复这个过程,直到基本满足期待的效果。如果一开始的效果就完全牛头不对马嘴,那也可以让它基于 Python 生成,等到效果尚可,再让它把代码转换成 C++ 代码。 经过多次调教,最终生成的代码如下: #include <iostream> #include <thread> #include <chrono> void print_progress_bar(int iteration, int total, int bar_length =… Continue Reading 借助 ChatGPT 快速实现一个轻量级的控制台进度条库

模板加约束,其中有迷思,着意分析一下。 template <typename T> void f(T t) {} template <typename T> void f(T t) requires true {} f(1); // the second one wins 二比一特殊,决战胜出,似乎全在预料之内。 根据 [temp.over.link]/7: Two function templates are equivalent if they are declared in the same scope, have the same name, have equivalent template-heads, and have return types,… Continue Reading T231212 Dummy Rquires Clause Positioning in Function Template Overloading

回顾上篇实现,可见会遇到内存重新分配问题,大文件读取存在隐性开销。 using result_type = std::vector<std::vector<std::string>>; auto read_csv(std::string_view file, std::string_view type = "", std::string_view delimiter = ",") -> std::optional<result_type> { std::ifstream data_file(file.data()); if (!data_file.is_open()) { return {}; } std::string line; std::getline(data_file, line); // skip the title result_type result; while (std::getline(data_file, line)) { auto tokens = line | std::views::split(delimiter) | std::views::transform([](auto&& token)… Continue Reading Memory Reallocation when Parsing CSV Files