1. 执行摘要

Qt 6 与 C++20 的结合是一种经过审慎管理的、务实的演进,而非一场激进的革命。该框架的核心策略是优先保障应用程序二进制接口(ABI)的稳定性与广泛的编译器兼容性,为此坚守 C++17 作为其基准标准。在此基础上,Qt 战略性地集成了能够提升性能、安全性与开发者体验的 C++20 特性,同时确保这些新功能不会破坏其核心承诺。

本报告的关键发现如下:

  • 直接集成: 对于那些主要基于头文件实现或拥有 C++17 兼容回退方案的特性,如三路比较运算符(operator<=>)、std::chrono 增强功能以及属性宏(Q_CONSTINIT),Qt 正在将其直接整合进框架中 1。
  • 桥接策略: 针对 std::span 这类对 ABI 敏感的特性,Qt 采用了一种“桥接”模式,创建了自身兼容的类型(QSpan)。该类型提供了与其 std 版本之间无缝的隐式转换,从而允许开发者在不强制要求所有用户都使用 C++20 工具链的情况下,采用现代化的代码模式 1。
  • 生态系统依赖: 对于协程(Coroutines)这类具有变革性但实现复杂的特性,Qt 目前依赖于更广泛的 C++ 生态系统。以 QCoro 为代表的第三方库已成为在 Qt 应用中利用这些新范式的行业标准,这展示了核心框架与社区创新之间共生共荣的关系 2。
  • 未来轨迹: Qt 6.10 中 QRangeModel 的引入,标志着 Qt 致力于将 C++20 的核心概念(如 Ranges)更深入地集成到其高级 API 中。这预示着未来将有更多此类功能成为框架的原生组成部分 3。

本报告的主要建议是:对于新的 Qt 6 项目,开发团队应采用 C++20 标准,以即刻从代码清晰度和安全性的提升中获益。然而,团队必须准备好应对工具链的复杂性,并依赖经过充分验证的第三方库来支持协程等主要特性。对于现有的 C++17 项目,推荐采用分阶段的现代化升级路径。

2. Qt 的 C++20 采纳策略:一场深思熟虑的演进

2.1. C++17 基础:优先保障稳定性与覆盖范围

Qt 6 的官方策略明确规定,其需要一个符合 C++17 标准的编译器 1。这一决策并非随意而为,而是一项战略性选择,旨在确保在各种编译器和平台上维持一个稳定的应用程序二进制接口(ABI)。这对于那些有长期支持(LTS)和认证需求的行业尤为重要 4。

一个稳定的 ABI 对 Qt 这样的基础库至关重要。它允许用户链接到预编译的 Qt 二进制文件,而无需重新编译整个框架,即便他们自己的应用程序代码使用了更新的 C++ 标准。这种做法避免了类似 GCC 在引入 C++11 时曾遇到的 std::string ABI 破坏等问题 5。通过将 C++17 作为基石,Qt 为其庞大的用户群提供了一个可靠且可预测的开发平台。

2.2. 条件性现代化:放宽 ABI 指导方针的提案

Qt 公司的一位首席软件工程师 Marc Mutz 在开发者邮件列表中发起了一场关键性的讨论,提议官方允许在 Qt 的 ABI 中使用 C++20 类型,例如 std::span 和协程 6。这项提案附带一个至关重要的条件:使用这些新 API 的项目将需要一个以 C++20(或更高版本)模式编译的 Qt 库。

该提案的论据在于,这种做法在 MSVC 编译器上已是既成事实,因为在 MSVC 中,导出类中的内联 API 已经是 ABI 的一部分 6。该提案旨在将此变为一项正式规定,从而催生更多现代化的、非内联的 API。对于使用 C++17 编译器的开发者来说,如果他们链接了一个 C++20 版本的 Qt 库并试图使用这些新 API,其后果将是一个清晰且易于管理的链接器错误(符号未找到),而不是难以诊断的运行时崩溃 6。这种清晰的失败模式使得风险可控,为渐进式采纳 C++20 铺平了道路。

2.3. 长期愿景:在进步与务实之间寻求平衡

根据 Qt 全球峰会 2023 的路线图摘要,Qt 的领导层展现了其前瞻性的战略 4。他们深刻理解,对于那些身处受监管行业、通常受限于 C++14 甚至更早标准的供应商而言,C++17 的引入已带来了挑战。

因此,Qt 的长期目标是使 C++20 和 C++23 的特性成为可选项。这意味着开发者不会因为升级到新版本的 Qt 6 而被迫升级其整个工具链。然而,那些有能力进行升级的开发者将能够解锁新的功能。这一策略很可能会持续到未来的主要版本(如 Qt 7)发布,届时 C++ 的基准标准才可能再次被提升。这种策略的背后,是一种深思熟虑的风险管理模式。Qt 将现代化的“风险”外部化,转移给了选择走在技术前沿的开发者。通过让 C++20 特性成为“选择性加入”(opt-in)项,Qt 保护了其在嵌入式和受监管行业中的庞大保守用户群,使他们免于被迫进行成本高昂且充满风险的工具链升级。这是一种允许框架在不抛弃其核心用户群的情况下持续演进的复杂而有效的风险管理策略。

3. 已集成的 C++20 特性:核心框架的增强

3.1. QSpan:一座连接 C++17 与 std::span 的桥梁

在 Qt 6.7 中引入的 QSpan 是 Qt 对 std::span 概念的独到诠释 1。它是一个 Qt 特定的实现,旨在 C++17 代码库中使用。其核心技术特性在于它能够与std::span 进行双向的隐式转换。

这一设计精妙之处在于,它允许开发者在自己的 C++20 应用程序代码中编写接受 std::span 的函数,并能无缝地将 Qt 容器(如 QList 或 QVector)传递给这些函数。编译器会自动将 Qt 容器转换为 QSpan,再进一步转换为 std::span。这种“桥接”功能是其设计的基石,使得 Qt 可以在其自身的 API 中使用类似 span 的语义,而无需破坏其对 C++17 ABI 的承诺。这为如何在不全面提升语言要求的情况下采纳现代 C++ 概念提供了一个范例。

3.2. 使用 operator<=> 实现比较现代化

C++20 的三路比较运算符(<=>,又称“太空船运算符”)极大地简化了比较逻辑的实现。Qt 6.8 已在许多 QtCore 类中采纳了这一特性 1。

至关重要的是,对于仍在使用 C++17 的开发者,Qt 提供了一套全面的回退系统。该系统的组成部分及其作用如下:

  • Qt::compareThreeWay():一个 C++17 兼容的函数,用于模拟 operator<=> 对基本类型的操作。
  • compareThreeWay() 隐藏友元(hidden friends):Qt 类内部用于提供自定义比较逻辑的模式。
  • qCompareThreeWay():一个通用的函数模板,它能分派到正确的实现,使得编写适用于内建类型和自定义 Qt 类型的通用比较代码变得简单 1。

这种双重系统再次印证了 Qt 的采纳策略:为能够使用新特性的开发者提供现代化的 C++20 功能,同时也为坚守 C++17 基准的用户提供源码兼容、功能强大的替代方案。

3.3. 利用 std::chrono 实现高级时间处理

尽管 Qt 对 std::chrono 早有支持,但 C++20 极大地扩展了该库,引入了日历、时区和更精确的时间点。当 Qt 以 C++20 模式编译时,QDate 和 QDateTime 获得了与这些新标准类型相互转换的能力。QTimeZone 不仅可以从 std::time_zone 构造,还可以选择性地使用 C++20 的 IANA 时区数据库(tzdb)作为其后端 1。

值得注意的是,在 Qt 6.9 中,tzdb 后端仍处于实验阶段。其主要原因是标准库在实现上存在不一致性,导致数据可能无法被忠实地表示 1。

3.4. 语法糖与安全性:实用工具宏

Qt 还通过宏采纳了一些虽小但重要的 C++20 特性,以确保编译器的兼容性:

  • Q_CONSTINIT:展开为 constinit,强制在编译时进行初始化,从而避免静态初始化顺序问题。
  • Q_NODISCARD_CTOR 和 Q_NODISCARD_X:提供了在构造函数上以及带原因说明的 [[nodiscard]] 属性的访问方式,通过防止意外丢弃重要的返回值,帮助开发者编写更安全的代码 1。

4. 异步编程:Qt 生态系统中的协程

4.1. 原生支持的缺失:为何 Qt API 中没有 co_await?

许多开发者感到困惑的一个关键点是:Qt 6 目前并未对其异步对象(如 QNetworkReply 或 QProcess)提供原生的、开箱即用的 co_await 支持。

集成协程是一项重大工程,远不止是简单的库功能添加。它涉及到对框架异步模式的深层改动,并带来显著的 ABI 影响,这与第二节中讨论的保守策略息息相关。事实上,Qt 早期的一个内部协程实现被发现与最终的 C++20 标准不兼容,导致尝试混合使用的用户遇到了链接器错误 8。这个例子凸显了早期采纳的风险,也为 Qt 采取谨慎态度提供了合理的解释。

4.2. QCoro:社区的回应与事实标准

原生支持的缺失创造了一个市场空白,而第三方库 QCoro 巧妙地填补了这一空白 2。本节将 QCoro 不仅仅视为一个库,而是现代 Qt 开发生态系统中的一个关键组成部分进行分析。

其核心特性包括:

  • 为核心的 Qt 异步类型提供 co_await 支持,涵盖 QNetworkReply、QProcess、QTimer、QIODevice、QFuture 和 QDBusPendingCall 2。
  • 其根本承诺是:让开发者能够编写读起来像同步代码的异步逻辑,而在挂起点(co_await)期间,Qt 事件循环能够不受阻碍地继续运行 9。
  • 同时支持 Qt 5 和 Qt 6,使其成为管理跨版本项目的多功能工具 2。

这种现象揭示了成熟软件生态系统中的一个经典模式。核心框架提供了稳定、基础的原语(如事件循环、QObject、信号与槽机制)。社区则在这些原语之上构建更现代化、更高级的抽象。QCoro 并非要取代 Qt 的事件循环,而是巧妙地利用了它。co_await 挂起了协程,但正是 Qt 的事件循环在维持应用程序的响应性,并最终通过信号触发协程的恢复。因此,Qt 缺乏原生协程支持并非一种失败,反而为生态系统的创新提供了土壤。QCoro 的成功可以为未来 Qt 版本(或许是 Qt 7)中可能的原生实现提供蓝图和概念验证。

4.3. 案例研究:QNetworkAccessManager 的现代化

为了提供具体的价值,本节将进行并排的代码比较。

之前 (C++17 信号/槽):
一个典型的使用 QNetworkAccessManager 的网络请求,需要连接 finished 信号,通常使用 lambda 表达式或一个单独的槽函数。当需要链接多个依赖请求时,这种风格很容易导致“回调地狱” 11。

// C++17 with Signals and Slots
void fetchData() {
auto manager = new QNetworkAccessManager(this);
connect(manager, &QNetworkAccessManager::finished, this, [=](QNetworkReply *reply) {
if (reply->error() == QNetworkReply::NoError) {
QByteArray data = reply->readAll();
// Process data…
} else {
// Handle error…
}
reply->deleteLater();
manager->deleteLater();
});
manager->get(QNetworkRequest(QUrl(“http://example.com/data.json”)));
}

之后 (C++20 与 QCoro):
使用 co_await 重写相同的网络请求。代码呈现为一个单一的、线性的函数,错误处理通过标准的 if/else 或 try/catch 块进行管理。这极大地提升了代码的可读性和可维护性 2。

// C++20 with QCoro
#include <QCoro/QCoroNetwork>

QCoro::Task<> fetchData() {
QNetworkAccessManager manager;
auto reply = co_await manager.get(QNetworkRequest(QUrl(“http://example.com/data.json”)));
if (reply->error() == QNetworkReply::NoError) {
QByteArray data = reply->readAll();
// Process data…
} else {
// Handle error…
}
reply->deleteLater();
}

5. 数据处理与模型/视图:std::ranges 的革命

5.1. Qt 容器与 C++20 Range 的兼容性

由于 Qt 的容器类(如 QList、QVector、QMap 等)提供了与 STL 兼容的迭代器(begin()、end()),它们通常可以作为基于范围的算法的输入,并能被适配为视图(views)13。这意味着开发者可以立即开始在他们现有的 Qt 数据结构上运用std::ranges 的表达能力,而无需等待任何特定的 Qt 更新。

例如,一个 QList 可以被直接传入一个由 std::views::filter 和 std::views::transform 构成的管道中,代码简洁而富有表现力 15。

#include <QList>
#include <QDebug>
#include <ranges>

void processWithRanges() {
QList<int> data = {1, 2, 3, 4, 5, 6};
auto processedView = data

std::views::filter((int n) { return n % 2 == 0; })
std::views::transform((int n) { return n * n; });
qDebug() << “Processed data:;
for (int value : processedView) {
qDebug() << value; // Outputs 4, 16, 36
}
}

5.2. QRangeModel:UI 开发的范式转变

QRangeModel 是 Qt 6.10 中引入的一个 beta 特性,它可能是 Qt 对 C++20 主要范式最重要的一次直接采纳 3。其核心价值在于,它极大地减少了在 Qt 模型/视图架构中展示 C++ 数据结构所需的样板代码。对于许多常见的列表和表格 UI,它使得编写自定义的QAbstractItemModel 子类变得不再必要 3。

QRangeModel 可以与多种 C++ 数据结构协同工作:

  • 从 std::vector 或 QList 创建简单的列表模型。
  • 从嵌套范围(如 std::vector<std::vector<T>>)创建表格模型。
  • 从元组或结构体的范围(如 std::vector<std::tuple<int, QString>>)创建表格模型 3。

通过指针或 std::ref 传递数据源,可以实现双向数据绑定,即 UI 上的修改会直接反映在 C++ 数据结构中 3。然而,也存在一些已知的限制,例如由于 C++20 中迭代器的约束,QRangeModel 与 std::views::filter 等某些视图不兼容,这个问题在 C++23 中得到了部分解决 3。

下表作为一个快速参考指南,展示了如何将不同的 C++ 数据源通过 QRangeModel 映射到具体的 UI 模型。

表 5.1: QRangeModel 数据源兼容性

C++ 数据源示例 生成的 QRangeModel 类型 UI 表现形式 是否可修改?
std::vector<int> 列表模型 QListView / ListView 是(若通过指针/引用传递)
std::views::iota(1, 10) 列表模型 QListView / ListView 否(只读视图)
std::vector<std::vector<int>> 表格模型 QTableView / TableView 是(若通过指针/引用传递)
std::vector<std::tuple<int, QString, bool>> 表格模型(3 列) QTableView / TableView 是(若通过指针/引用传递)
std::array<MyStruct, 5> 表格模型(列来自结构体成员) QTableView / TableView 是(若通过指针/引用传递)

6. 前瞻:C++20 Concepts 与未来 API

6.1. 采纳现状:谨慎的开端

截至最新版本,C++20 Concepts 在 Qt 6 的公共 API 中的使用仍然非常有限,甚至可以说尚未开始 16。这种谨慎的态度与其核心战略一脉相承:Concepts 是一个编译时特性,用它来约束一个公共模板函数会从根本上改变其接口。这样做将要求该 API 的所有用户都拥有支持 Concepts 的编译器,这会违反 Qt 对 C++17 基准的保证。

6.2. 内部使用与向后移植:q20algorithm.h

对 Qt 内部头文件如 q20algorithm.h 的深入分析,揭示了 Qt 的内部策略 19。该文件表明,Qt 的开发者正在内部积极使用并为 C++20 的特性做准备。它提供了 STL 算法的constexpr 版本和范围算法的无约束版本,并在编译器支持时通过 #ifdef __cpp_lib_constexpr_algorithms 将它们别名到 std:: 版本。

文件顶部的警告信息至关重要,它明确指出这些是临时的向后移植,一旦 Qt 依赖的 C++ 版本原生支持这些特性,它们“将会直接消失”,而不会有任何弃用警告 19。这向社区传递了一个清晰的信号,即 Qt 内部现代化的路径和决心。

6.3. 潜在影响:一个更安全、更富表现力的 Qt

展望未来,Concepts 有可能在 Qt 7 或更远的版本中改变 Qt 的 API。

  • 改进的错误信息: Concepts 将解决传统模板替换失败时产生的难以理解的错误信息,代之以清晰的约束未满足的说明 20。
  • 自文档化的 API: 一个类似 template<Container C> void process(const C& container) 的函数签名,其表达能力远超当前的 template<typename C>。
  • 更安全的泛型代码: Concepts 将允许 Qt 自身的模板类和算法通过明确定义其操作类型的要求而变得更加健壮。

7. 开发者指南:实践与陷阱

7.1. 工具链要求:编译器与版本

为 Qt 6 搭建 C++20 开发环境,需要满足特定的工具链要求。下表为开发者提供了一个具体、可靠的配置起点,整合了来自编译器文档、第三方库要求和社区论坛的信息。

表 7.1: Qt 6 使用 C++20 的最低编译器版本建议

编译器 最低推荐版本 关键考量 / 已知问题
GCC 11+ 协程支持需要 -fcoroutines 编译标志 9。从该版本起,C++20 支持普遍稳定。
Clang 15+ 协程可能需要 -fcoroutines-ts 标志 9。在 Windows 上,需在 Qt Creator 中仔细配置 Kit,使用 win32-clang-msvc mkspec,以确保与 MSVC 编译的 Qt 库的 ABI 兼容性 23。
MSVC Visual Studio 2022 (v17.0 / 19.30+) 使用 /std:c++20 或 /std:c++latest 时,协程支持默认开启 9。C++20 标准符合性极佳 25,但早期版本对某些特性的支持不完整或存在缺陷 26。

7.2. 构建系统配置:CMake 与 Conan

在构建系统中正确配置 C++20 标准至关重要,否则可能导致难以排查的问题。

  • CMake: 启用 C++20 的标准做法是使用 set(CMAKE_CXX_STANDARD 20) 和set(CMAKE_CXX_STANDARD_REQUIRED ON) 27。
  • Conan: 一个真实世界的案例显示,使用 Conan 构建 Qt 时,compiler.cppstd=20 的设置未能正确传递,导致 Qt 仍以 C++17 模式编译,最终在链接应用程序时引发错误 8。解决方案在于确保 Conan 的 Qt 配方(recipe)正确使用了QT_FEATURE_cxx 等变量 8。
  • Qt Creator: 有时即使项目能够成功编译,IDE 的代码模型也可能无法识别 C++20 语法。这通常可以通过在 IDE 的首选项中正确配置 clangd 来解决 29。

7.3. 现代化模式:从 C++17/Qt 到 C++20

以下是一些常见任务的“前后对比”代码示例,以展示现代化重构的价值。

  • 字符串格式化:
    • 传统方式: QString(“…”).arg(a).arg(b) 模式在 Qt 中历史悠久且方便 30。
    • 现代方式: C++20 的 std::format 提供了类型安全且功能强大的类 Python 格式化能力。
  • 比较操作:
    • 传统方式: 手动实现 operator<、operator== 等所有六个比较运算符。
    • 现代方式: 只需实现一个默认的 operator<=>,编译器将自动生成其余的运算符,从而大幅减少样板代码。
  • 异步代码:
    • 请参考 4.3 节中关于 QNetworkAccessManager 的案例研究,它清晰地展示了从信号/槽到 co_await 的转变所带来的代码可读性的巨大提升。

8. 结论与战略建议

8.1. 调查结果总结

Qt 6 对 C++20 的支持并非一个简单的“是”或“否”的问题,而是一项多层面、持续进行的战略。它通过在稳定的 C++17 基础上构建,同时提供选择性加入现代 C++20 特性的途径,成功地平衡了其多元化用户群的需求。这一策略的特点是:直接集成非破坏性特性,使用 QSpan 等兼容性桥梁,以及健康地依赖社区生态系统来探索协程等前沿范式。

8.2. 采纳建议

  • 对于新项目(“绿地”项目): 强烈建议直接从 C++20 工具链开始。在代码表达能力、安全性以及对 std::ranges 和 QCoro 等现代库的访问方面,C++20 提供了显著的长期优势。
  • 对于现有项目(“棕地”项目): 推荐采用渐进式、有针对性的现代化方法。
    1. 首先,更新工具链并在构建系统中启用 C++20。
    2. 其次,专注于“低垂的果实”:将复杂的比较逻辑重构为 operator<=>,采用 std::span 来表达视图语义,并在适用之处使用新的 std::chrono 特性。
    3. 最后,对于复杂的异步代码,评估引入 QCoro 等依赖项,将关键的“回调地狱”部分重构为更易于维护的协程。
  • 对所有团队的忠告: 必须强调严格的工具链管理。Qt 对 C++20 的条件性支持意味着,确保用于构建 Qt 库的 C++ 标准与用于构建应用程序的标准保持一致,是避免隐晦且令人沮丧的链接器错误的关键 8。
引用的著作
  1. C++20 Overview | Qt Core | Qt 6.9.2, 访问时间为 九月 17, 2025, https://doc.qt.io/qt-6/cpp20-overview.html
  2. qcoro/qcoro: C++ Coroutines for Qt - GitHub, 访问时间为 九月 17, 2025, https://github.com/qcoro/qcoro
  3. A Model for all Ranges - Qt, 访问时间为 九月 17, 2025, https://www.qt.io/blog/a-model-for-all-ranges
  4. Qt Roadmap QtWS 23 : r/QtFramework - Reddit, 访问时间为 九月 17, 2025, https://www.reddit.com/r/QtFramework/comments/18jpcqg/qt_roadmap_qtws_23/
  5. Is it possible to build QT 6.2.2 with C++20? - Qt Forum, 访问时间为 九月 17, 2025, https://forum.qt.io/topic/132571/is-it-possible-to-build-qt-6-2-2-with-c-20
  6. [Development] Proposing to officially allow C++20 types in Qt 6 ABIs - Mailing Lists, 访问时间为 九月 17, 2025, https://lists.qt-project.org/pipermail/development/2022-January/042151.html
  7. C++20 comparison in Qt (even with C++17 ), 访问时间为 九月 17, 2025, https://www.qt.io/blog/c20-comparisons-in-qt
  8. [package] qt/6.4.1: compiles as c++17 despite setting c++20 #15001 - GitHub, 访问时间为 九月 17, 2025, https://github.com/conan-io/conan-center-index/issues/15001
  9. QCoro, 访问时间为 九月 17, 2025, https://qcoro.dev/
  10. Qt vs. co_await - QCoro, 访问时间为 九月 17, 2025, https://qcoro.dev/coroutines/qt-vs-coawait/
  11. QNetworkAccessManager Class | Qt Network | Qt 6.9.2, 访问时间为 九月 17, 2025, https://doc.qt.io/qt-6/qnetworkaccessmanager.html
  12. QT - Code Snippet for QNetworkRequest Lambda Callback with Connect - Joshua Tzucker, 访问时间为 九月 17, 2025, https://joshuatz.com/posts/2019/qt-code-snippet-for-qnetworkrequest-lambda-callback-with-connect/
  13. Container Classes | Qt Core | Qt 6.9.2, 访问时间为 九月 17, 2025, https://doc.qt.io/qt-6/containers.html
  14. Understand the Qt containers | -Wmarc - WordPress.com, 访问时间为 九月 17, 2025, https://marcmutz.wordpress.com/effective-qt/containers/
  15. The Ranges Library in C++20 | Qt Training Services, 访问时间为 九月 17, 2025, https://www.learnqt.guide/cpp-20-ranges
  16. Qt Examples And Tutorials | Qt 6.9 - Qt Documentation, 访问时间为 九月 17, 2025, https://doc.qt.io/qt-6/qtexamplesandtutorials.html
  17. 2017-January.txt - Mailing Lists - The Qt Project, 访问时间为 九月 17, 2025, https://lists.qt-project.org/pipermail/interest/2017-January.txt
  18. [Development] Qt wrapper for UPC UA Server stack (open62541), 访问时间为 九月 17, 2025, https://lists.qt-project.org/pipermail/development/2019-April/035636.html
  19. q20algorithm.h source code [qtbase/src/corelib/global/q20algorithm.h] - Codebrowser, 访问时间为 九月 17, 2025, https://codebrowser.dev/qt6/qtbase/src/corelib/global/q20algorithm.h.html
  20. The Complete Guide to C++20 Concepts: Revolutionizing Template Programming, 访问时间为 九月 17, 2025, https://blog.devgenius.io/the-complete-guide-to-c-20-concepts-revolutionizing-template-programming-419a5091f08c
  21. Using C++ concepts for great good 😃 part 1 | by gianni ‍♂️ | Medium, 访问时间为 九月 17, 2025, https://gkteco.medium.com/using-c-concepts-for-great-good-part-1-2ae42c7a0d6d
  22. My tutorial and take on C++20 coroutines, 访问时间为 九月 17, 2025, https://www.scs.stanford.edu/~dm/blog/c+±coroutines.html
  23. [Development] QThread::create mandatory in Qt 6? - Mailing Lists, 访问时间为 九月 17, 2025, https://lists.qt-project.org/pipermail/development/2020-November/040607.html
  24. How to use Clang as a compiler with Qt Creator on Windows? - Stack Overflow, 访问时间为 九月 17, 2025, https://stackoverflow.com/questions/32533043/how-to-use-clang-as-a-compiler-with-qt-creator-on-windows
  25. Microsoft C/C++ language conformance by Visual Studio version, 访问时间为 九月 17, 2025, https://learn.microsoft.com/en-us/cpp/overview/visual-cpp-language-conformance?view=msvc-170
  26. Compiler support for C++20 - cppreference.com, 访问时间为 九月 17, 2025, https://en.cppreference.com/w/cpp/compiler_support/20.html
  27. Thread: Can not use the modules feature from c++20 with Qt Creator and VS, 访问时间为 九月 17, 2025, https://www.qtcentre.org/threads/72078-Can-not-use-the-modules-feature-from-c-20-with-Qt-Creator-and-VS
  28. Qt requires a C++ 17 compiler, not resolved within CMake and Visual Studio - Reddit, 访问时间为 九月 17, 2025, https://www.reddit.com/r/QtFramework/comments/1fqgzxy/qt_requires_a_c_17_compiler_not_resolved_within/
  29. How to get Qt Creator to support C++20 in its editor with CMake - Stack Overflow, 访问时间为 九月 17, 2025, https://stackoverflow.com/questions/79653064/how-to-get-qt-creator-to-support-c20-in-its-editor-with-cmake
  30. How to format a QString? - c++ - Stack Overflow, 访问时间为 九月 17, 2025, https://stackoverflow.com/questions/4784155/how-to-format-a-qstring
  31. Good way to use QString.arg() to just format an int? - Qt Centre Forum, 访问时间为 九月 17, 2025, https://www.qtcentre.org/threads/69842-Good-way-to-use-QString-arg()-to-just-format-an-int
Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐