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

第十七章:Future Directions_《C++ Templates》notes

Future Directions

        • 核心重难点:
        • 示例代码:
      • 设计题
        • 多选题答案
        • 设计题详解


核心重难点:
  1. 泛型非类型模板参数

    • 允许任意类型作为非类型模板参数(如template<typename T, auto N>
    • 需解决类型推导和链接问题
  2. 编译期控制流

    • constexpr if替代模板偏特化(减少代码膨胀)
    • 折叠表达式优化可变参数模板处理
  3. 反射与元编程增强

    • 类型检查(is_convertible_v等)
    • 反射提案(如成员变量/函数查询)
  4. 模块化支持

    • 解决传统头文件包含模型的编译效率问题
    • 显式实例化与模块接口的交互
  5. 语法简化

    • 放宽typename使用限制
    • void类型规范化(统一处理无返回值函数)

Concepts(概念)
功能:通过显式约束模板参数类型,提升编译时类型检查和错误提示的可读性。

示例代码:
#include <iostream>
#include <vector>
#include <concepts>// 定义一个Concept,要求类型支持加法运算
template<typename T>
concept Addable = requires(T a, T b) {{ a + b } -> std::same_as<T>;
};// 使用Concept约束模板参数
template<Addable T>
T add(T a, T b) {return a + b;
}int main() {std::cout << add(1, 2) << std::endl;          // 输出3(int满足Addable)std::cout << add(1.5, 2.5) << std::endl;      // 输出4(double满足Addable)// std::vector<int>不满足Addable(无operator+),编译报错// std::cout << add(std::vector<int>{1}, std::vector<int>{2}) << std::endl;return 0;
}

编译命令(需支持C++20):

g++ -std=c++20 concepts.cpp -o concepts

Modules(模块)
功能:替代传统头文件,提升编译速度和封装性。

示例代码:
math_module.ixx(模块接口文件):

export module math;export template<typename T>
T add(T a, T b) {return a + b;
}

main.cpp(使用模块):

import math;int main() {std::cout << add(3, 5) << std::endl;  // 输出8return 0;
}

编译命令(需支持C++20模块):

g++ -std=c++20 -fmodules-ts -c math_module.ixx -o math_module.o
g++ -std=c++20 -fmodules-ts main.cpp math_module.o -o main

17.6 Deduction for Nonfinal Pack Expansions(非终结包展开推导)
功能:允许在模板参数包展开时进行类型推导。

示例代码:

#include <iostream>
#include <tuple>// 推导包展开中的类型
template<typename... Ts>
auto make_tuple_and_print(Ts&&... args) {auto t = std::make_tuple(std::forward<Ts>(args)...);std::cout << "Tuple elements: ";((std::cout << args << " "), ...);std::cout << std::endl;return t;
}int main() {auto t = make_tuple_and_print(1, 2.5, "Hello");// 输出类型:std::tuple<int, double, const char*>return 0;
}

编译命令

g++ -std=c++20 pack_deduction.cpp -o pack_deduction

关键知识点总结

特性核心优势典型应用场景
Concepts显式约束模板参数,增强编译错误信息泛型算法、类型安全检查
Modules替代头文件,避免宏污染,提升编译速度大型项目模块化管理
包展开推导简化变长模板参数处理,支持复杂类型构造元编程、通用容器实现

扩展练习
尝试实现一个使用Concepts约束的Comparable概念,并编写一个通用的比较函数模板:

#include <iostream>
#include <concepts>template<typename T>
concept Comparable = requires(T a, T b) {{ a == b } -> std::convertible_to<bool>;{ a != b } -> std::convertible_to<bool>;
};template<Comparable T>
bool safe_compare(const T& a, const T& b) {return a == b;
}int main() {std::cout << std::boolalpha;std::cout << safe_compare(10, 20) << std::endl;       // 输出falsestd::cout << safe_compare(std::string("Hello"), std::string("World")) << std::endl;  // 输出false// std::vector<int>无法比较,编译报错// safe_compare(std::vector<int>{1}, std::vector<int>{2});return 0;
}

多选题

题目1:关于C++20 concept的描述正确的是?
A. 必须在模板参数列表中使用requires子句
B. 可以定义默认约束条件
C. 支持逻辑运算符组合约束
D. 能够自动推导约束条件


题目2:constexpr if与普通if的关键区别是?
A. 编译期求值条件
B. 支持非布尔类型条件
C. 分支代码生成策略不同
D. 可以出现在类外定义

答案:A、C

解析:

  • A正确:条件在编译期求值
  • C正确:不满足条件的分支会被丢弃(SFINAE)
  • B错误:必须为布尔常量表达式
  • D错误:仅限函数作用域

题目3:泛型lambda的捕获列表中可以出现?
A. auto类型占位符
B. 静态成员变量
C. 非静态成员函数指针
D. 模板参数包

答案:B、C

解析:

  • B正确:可以捕获静态成员(如[=] { return MyClass::value; }
  • C正确:可以捕获成员函数指针(如[&f] { return obj.*f(); }
  • A错误:捕获列表不支持auto
  • D错误:模板参数包无法直接捕获

题目4:关于折叠表达式的错误说法是?
A. 支持所有二元操作符
B. 可以展开参数包到逗号表达式
C. 空包展开有明确定义
D. 左右折叠优先级相同

答案:A、D

解析:

  • A错误:不支持||, &&, ,以外的操作符需要括号包裹
  • D错误:左折叠(args + ...)和右折叠(... + args)优先级不同
  • B正确:可以展开到逗号表达式(如([](auto x){}, ...)
  • C正确:空包左折叠为identity,右折叠为identity

题目5:C++23中std::type_identity_t的主要用途是?
A. 禁止类型推导
B. 强制类型转换
C. 消除ADL影响
D. 延迟模板实例化

答案:A、C

解析:

  • A正确:std::type_identity_t<T>阻止T被推导(如decltype(auto) = std::type_identity_t<int>{}
  • C正确:消除ADL查找(如std::type_identity_t<decltype(f)>::type
  • B错误:不改变类型本质
  • D错误:不影响实例化时机

题目6:关于模块化的正确说法是?
A. 模块接口单元必须使用export关键字
B. 模块实现单元可以包含#include指令
C. 模块可以导出宏定义
D. 模块编译单元之间自动处理依赖关系

答案:A、D

解析:

  • A正确:模块接口需显式导出实体(如export module M; export int f();
  • D正确:模块编译器自动管理依赖传递
  • B错误:实现单元不应包含#include
  • C错误:宏无法跨模块可见

题目7:C++20 requires子句可以用于?
A. 函数模板约束
B. 类模板约束
C. 变量模板约束
D. 构造函数约束

答案:A、B、C、D

解析:

  • 所有选项均正确:requires可用于任何模板声明的约束(如template<typename T> requires C<T> class C {};

题目8:关于[[nodiscard]]属性的模板化用法正确的是?
A. 可以作用于类模板
B. 可以作用于函数模板
C. 可以作用于变量模板
D. 无法作用于成员模板

答案:A、B、C

解析:

  • A正确:[[nodiscard]] struct S {};
  • B正确:[[nodiscard]] template<typename T> T f();
  • C正确:[[nodiscard]] template<typename T> T x;
  • D错误:成员模板同样可以标记(如class C { [[nodiscard]] T f(); };

题目9:C++23中std::is_constant_evaluated()的典型应用场景是?
A. 禁止编译期计算
B. 优化运行时分支
C. 实现编译期调试输出
D. 检测异常安全等级

答案:B、C

解析:

  • B正确:避免编译期不必要的开销(如if (!std::is_constant_evaluated()) { /* runtime code */ }
  • C正确:在编译期执行日志输出(需配合if constexpr
  • A错误:无法禁止编译期计算
  • D错误:与异常安全无关

题目10:关于std::format与模板的结合错误说法是?
A. 可以格式化任意类型(需自定义formatter
B. 支持编译期字符串检查
C. 自动推导格式说明符
D. 比printf更易出错

答案:C、D

解析:

  • C错误:需显式指定格式说明符(如std::format("{:.2f}", 3.1415)
  • D错误:类型安全优于printf
  • A正确:通过ADL注册自定义格式化器
  • B正确:constexpr上下文支持编译期检查

设计题

题目1:实现一个支持编译期字符串拼接的concat模板

#include <iostream>
#include <string_view>template<std::size_t N, std::size_t M>
constexpr auto concat(const char(&a)[N], const char(&b)[M]) {std::array<char, N + M - 1> result{};std::copy_n(a, N-1, result.begin());std::copy_n(b, M, result.begin() + N - 1);return result;
}int main() {constexpr auto str = concat("Hello", " World!");static_assert(str == "Hello World!");std::cout << str.data() << std::endl;
}

题目2:使用constexpr if优化斐波那契数列计算

#include <iostream>template<int N>
constexpr int fib() {if constexpr (N <= 1) return N;return fib<N-1>() + fib<N-2>();
}int main() {static_assert(fib<10>() == 55);std::cout << "Fibonacci(10): " << fib<10>() << std::endl;
}

题目3:实现类型安全的变长参数包装器

#include <tuple>
#include <iostream>template<typename... Args>
void log(Args&&... args) {((std::cout << std::forward<Args>(args) << " "), ...);std::cout << std::endl;
}int main() {log("Hello", 42, 3.14, std::string("World"));
}

题目4:基于std::variant的类型安全访问器

#include <variant>
#include <iostream>
#include <string>template<typename... Ts>
struct overloaded : Ts... { using Ts::operator()...; };
template<typename... Ts> overloaded(Ts...) -> overloaded<Ts...>;int main() {std::variant<int, std::string> v = "Hello";std::visit(overloaded{[](int i) { std::cout << "int: "<< i << std::endl; },[](const std::string& s) { std::cout << "string: "<< s << std::endl; }}, v);
}

题目5:编译期素数检测

#include <iostream>
#include <bit>template<unsigned N, unsigned D>
struct is_prime_helper {static constexpr bool value = (N % D != 0) && is_prime_helper<N, D-1>::value;
};template<unsigned N>
struct is_prime_helper<N, 1> {static constexpr bool value = true;
};template<unsigned N>
constexpr bool is_prime() {if constexpr (N < 2) return false;return is_prime_helper<N, N/2>::value;
}int main() {static_assert(is_prime<7>());static_assert(!is_prime<9>());std::cout << "Is 13 prime? " << std::boolalpha << is_prime<13>() << std::endl;
}

多选题答案
  1. 答案:B、C

解析:

  • B正确:concept可以定义默认约束(如template<typename T> concept C = ...
  • C正确:支持&&, ||, !组合约束(如C1 && !C2)
  • A错误:C++20允许隐式约束(无需requires
  • D错误:约束需显式声明
  1. 答案:A、C

    • constexpr if在编译期求值条件并丢弃不满足的分支
  2. 答案:B、C

    • 泛型lambda可捕获静态成员和成员函数指针
  3. 答案:A、D

    • 折叠表达式不支持所有操作符且左右折叠优先级不同
  4. 答案:A、C

    • std::type_identity_t阻止类型推导并消除ADL影响
  5. 答案:A、D

    • 模块需显式导出实体且自动处理依赖关系
  6. 答案:A、B、C、D

    • requires可约束所有模板类型
  7. 答案:A、B、C

    • [[nodiscard]]可修饰类/函数/变量模板
  8. 答案:B、C

    • std::is_constant_evaluated()优化运行时分支和调试输出
  9. 答案:C、D

    • std::format需显式指定格式且比printf更安全
设计题详解
  1. 编译期字符串拼接

    • 使用std::array存储结果,递归拼接字符数组
  2. 斐波那契数列优化

    • constexpr if终止递归条件,避免无限展开
  3. 变长参数包装器

    • 折叠表达式展开参数包,完美转发所有参数
  4. 类型安全访问器

    • std::visit结合overloaded实现多态访问逻辑
  5. 编译期素数检测

    • 递归模板实现试除法,std::bit辅助优化

相关文章:

第十七章:Future Directions_《C++ Templates》notes

Future Directions 核心重难点&#xff1a;示例代码&#xff1a; 设计题多选题答案设计题详解 核心重难点&#xff1a; 泛型非类型模板参数 允许任意类型作为非类型模板参数&#xff08;如template<typename T, auto N>&#xff09;需解决类型推导和链接问题 编译期控制…...

NVIDIA Dynamo源码编译

Ref https://github.com/PyO3/maturin Rust 程序设计语言 代码库&#xff1a; https://github.com/ai-dynamo/dynamo https://github.com/ai-dynamo/nixl dynamo/container/Dockerfile.vllm 相关whl包 官方提供了4个whl包 ai_dynamo # 这个包ubuntu 22.04也可以用&…...

【前端】Canvas画布实现在线的唇膏换色功能

【前端】Canvas画布实现在线的唇膏换色功能 推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战目录 【前端】Canvas画布实现在线的唇膏换色功能背景概述以下是我们的实现方法!第一步 — 找…...

arcgispro加载在线地图

World_Imagery (MapServer)https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer添加arcgis server WMTS 服务 by xdcxdc.at xdc的个人站点。博客请转至 http://i.xdc.at/ http://xdc.at/map/wmts 添加WMTS服务器...

华为网路设备学习-16 虚拟路由器冗余协议(VRRP)

VRRP是针对干线上三层网络设备&#xff08;如&#xff1a;路由器、防火墙等&#xff09;的网络虚拟化技术&#xff0c;提供冗余和状态监测等功能。确保在网络中的单点故障发生时&#xff0c;能够快速切换到备份设备&#xff0c;从而保证网络通信的连续性和可靠性。‌ VRRP通过…...

使用请求调用本地部署的stable-diffusion接口

stable-diffusion-webui项目地址 具体部署教程请去B站寻找或者直接使用整合包 这里直接编写工具类 public class StableDiffusionUtil {private static final String BASE_URL "http://127.0.0.1:7860";private static final OkHttpClient CLIENT new OkHttpClien…...

封装一个分割线组件

最终样式 Vue2代码 <template><div class"sep-line"><div class"sep-label"><span class"sep-box-text"><slot>{{ title }}</slot> <!-- 默认插槽内容&#xff0c;如果没有传递内容则使用title -->&…...

网络HTTPS协议

Https HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff09;是 HTTP 协议的加密版本&#xff0c;它使用 SSL/TLS 协议来加密客户端和服务器之间的通信。具体来说&#xff1a; • 加密通信&#xff1a;在用户请求访问一个 HTTPS 网站时&#xff0c;客户端&#x…...

CMake 函数和宏

CMake 函数 CMake 函数定义语法如下, 其中 name 为函数名, <arg1> 为参数名, <commands> 为函数体. 函数定义后, 可以通过 name 调用函数. 函数名允许字母数字下划线, 不区分大小写. function(name [<arg1> ...])<commands> endfunction()如下的样例…...

OSASIS(One-Shot Structure-Aware Stylized Image Synthesis)

文章目录 摘要abstract论文摘要方法损失函数实验结论 总结 摘要 本周阅读了一篇关于新型图像风格化的论文《One-Shot Structure-Aware Stylized Image Synthesis》&#xff0c;旨在解决现有GAN模型在风格化过程中难以保持输入图像结构的问题。通过分离图像的结构和语义信息&am…...

C++学习之网盘项目单例模式

目录 1.知识点概述 2.单例介绍 3.单例饿汉模式 4.饿汉模式四个版本 5.单例类的使用 6.关于token的作用和存储 7.样式表使用方法 8.qss文件中选择器介绍 9.qss文件样式讲解和测试 10.qss美化登录界面补充 11.QHTTPMULTIPART类的使用 12.文件上传协议 13.文件上传协议…...

Leetcode—15. 三数之和(哈希表—基础算法)

题目&#xff1a; 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的…...

Apache Flink技术原理深入解析:任务执行流程全景图

前言 本文隶属于专栏《大数据技术体系》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见大数据技术体系 思维导图 📌 引言 Apache Flink 作为一款高性能的分布式流处理引擎,其内部执行机制精妙而复杂。本文将…...

DeepBI:重构流量逻辑,助力亚马逊广告实现高效流量增长

在日益激烈的跨境电商竞争环境中&#xff0c;广告投放早已从“粗放撒网”走向“精细化运营”。尤其是在亚马逊这样一个成熟且竞争白热化的平台&#xff0c;如何在广告预算有限的前提下实现高效曝光、精准触达、稳定转化&#xff0c;成为众多卖家和运营团队面临的核心挑战。 De…...

RAG(Retrieval-Augmented Generation)基建之PDF解析的“魔法”与“陷阱”

嘿&#xff0c;亲爱的算法工程师们&#xff01;今天咱们聊一聊PDF解析的那些事儿&#xff0c;简直就像是在玩一场“信息捉迷藏”游戏&#xff01;PDF文档就像是个调皮的小精灵&#xff0c;表面上看起来规规矩矩&#xff0c;但当你想要从它那里提取信息时&#xff0c;它就开始跟…...

C语言【文件操作】详解中(会使用fgetc,fputc,fgets,fputs,fscanf,fprintf,fread,fwrite函数)

引言 介绍和文件操作中文件的顺序读写相关的函数 看这篇博文前&#xff0c;希望您先仔细看一下这篇博文&#xff0c;理解一下文件指针和流的概念&#xff1a;C语言【文件操作】详解上-CSDN博客文章浏览阅读606次&#xff0c;点赞26次&#xff0c;收藏4次。先整体认识一下文件是…...

【Python Cookbook】字符串和文本(一)

字符串和文本&#xff08;一&#xff09; 1.使用多个界定符分割字符串2.字符串开头或结尾匹配3.用 Shell 通配符匹配字符串4.字符串匹配和搜索5.字符串搜索和替换 1.使用多个界定符分割字符串 你需要将一个字符串分割为多个字段&#xff0c;但是分隔符&#xff08;还有周围的空…...

GpuGeek:破解算力难题,赋能AI创新与普及

文章目录 一、引言二、填补算力资源供需缺口&#xff0c;降低使用门槛三、提升算力资源利用率&#xff0c;推动高效协作四、满足多样化需求&#xff0c;支持AI技术落地五、推动算力市场创新&#xff0c;促进生态良性发展六、助力AI人才培养&#xff0c;推动行业长远发展七、结语…...

扣子平台知识库不能上传成功

扣子平台知识库不能上传成功 目录 扣子平台知识库不能上传成功查看模板复制头部到自己的excel中json数据转为excel或者csv&#xff08;一定使用excel&#xff0c;csv总是报错&#xff09; 查看模板复制头部到自己的excel中 json数据转为excel或者csv&#xff08;一定使用excel&…...

蓝桥杯 R格式

问题描述 小蓝最近在研究一种浮点数的表示方法&#xff1a;R 格式。 对于一个大于 0 的浮点数 d&#xff0c;可以用 R 格式的整数来表示。 给定一个转换参数 n&#xff0c;将浮点数转换为 R 格式整数的做法是&#xff1a; 将浮点数乘以 2^n&#xff1b;将结果四舍五入到最接…...

计算机视觉的多模态模型

计算机视觉的多模态模型 是指能够同时处理和理解 多种类型数据&#xff08;模态&#xff09; 的模型。这些模态可以包括图像、文本、音频、视频、深度信息等。多模态模型的核心目标是利用不同模态之间的互补信息&#xff0c;提升模型的性能和泛化能力。 1. 多模态模型的核心思想…...

JVM的组成--运行时数据区

JVM的组成 1、类加载器&#xff08;ClassLoader&#xff09; 类加载器负责将字节码文件从文件系统中加载到JVM中&#xff0c;分为&#xff1a;加载、链接&#xff08;验证、准备、解析&#xff09;、和初始化三个阶段 2、运行时数据区 运行时数据区包括&#xff1a;程序计数…...

c++进阶之------红黑树

一、概念 红黑树&#xff08;Red-Black Tree&#xff09;是一种自平衡二叉查找树&#xff0c;它在计算机科学的许多领域中都有广泛应用&#xff0c;比如Java中的TreeMap和C中的set/map等数据结构的底层实现。红黑树通过在每个节点上增加一个颜色属性&#xff08;红色或黑色&am…...

《鸿蒙原生应用开发:掌控Ability生命周期的艺术》

在鸿蒙原生应用开发的广袤天地中&#xff0c;Ability作为构建应用的基本单元&#xff0c;其生命周期的有效管理宛如基石之于高楼&#xff0c;是打造稳定、高效且用户体验卓越应用的关键所在。随着鸿蒙生态的蓬勃发展&#xff0c;深入理解并巧妙运用Ability生命周期&#xff0c;…...

ubuntu22.04安装搜狗输入法保姆教程~

一、添加中文语言支持 1.首先打开设置,找到Language and Region 2.点击Manage Installed Languages 3.点击 Install/Remove Languages... 4.选中Chinese (simplified),点击Apply...

《数据库原理》SQLServer期末复习_题型+考点

目录 题型&#xff1a; 一. 概况分析题&#xff08;5小题&#xff0c;每小题2分&#xff0c;共10分&#xff09; 二. 计算题&#xff08;3小题&#xff0c;每小题5分&#xff0c;共15分&#xff09; 三. 数据库设计&#xff08;2小题&#xff0c;每小题10分&#xff0c;共2…...

Zstd(Zstandard)压缩算法

要压缩的数据量越小&#xff0c;压缩的难度就越大。这个问题对所有压缩算法都是通用的&#xff0c;原因是压缩算法从过去的数据中学习如何压缩未来的数据。但是&#xff0c;在新数据集开始时&#xff0c;没有“过去”可以构建。 官网 为了解决这种情况&#xff0c;Zstd 提供了一…...

烧结银技术赋能新能源汽车超级快充与高效驱动

烧结银技术赋能新能源汽车超级快充与高效驱动 在新能源汽车领域&#xff0c;高压快充技术的突破与高功率密度驱动系统的创新正成为行业竞争的焦点。比亚迪于 2025 年发布的超级 e 平台&#xff0c;通过整合全域千伏高压架构、兆瓦级闪充技术及碳化硅&#xff08;SiC&#xff0…...

本地部署 browser-use

本地部署 browser-use 0. 引言1. 核心功能与优势2. 快速上手3. 部署 Gradio UI4. 更多示例0. 引言 Browser-Use 是一个强大的工具,旨在让 AI Agent 能够控制浏览器,从而实现各种自动化任务。它简化了 AI 与浏览器的交互,让开发者能够轻松构建能够执行网页操作的智能应用。本…...

笔记:代码随想录算法训练营day59:110.字符串接龙 、105.有向图的完全可达性、106.岛屿的周长

学习资料&#xff1a;代码随想录 110. 字符串接龙 卡码网题目链接&#xff08;ACM模式&#xff09; 还是有些许复杂&#xff0c;要把字符串从begin开始遍历&#xff0c;然后把每一个字母都换一下&#xff0c;看能否在字典里找到&#xff0c;如果能找到就入队列并记录&#x…...