template<typename R = void> 意义

在 C++ 中,template<typename R = void> 表示定义一个模板参数 R,其默认类型为 void。这意味着:

  1. 如果用户没有显式指定 R,则 R 默认为 void
  2. 如果用户显式指定了 R(如 template<typename R = void> 后面跟着 <int>),则 R 会被替换为指定的类型(如 int)。

1. 基本用法

1.1 默认模板参数 void

template<typename R = void>
class MyClass {
public:
using ResultType = R; // 定义一个类型别名
};
int main() {
MyClass<> obj1; // R 默认为 void
MyClass<int> obj2; // R 显式指定为 int
// 检查类型
static_assert(std::is_same_v<MyClass<>::ResultType, void>); // true
static_assert(std::is_same_v<MyClass<int>::ResultType, int>); // true
}
  • MyClass<> 使用默认模板参数 void
  • MyClass<int> 显式指定 R 为 int

1.2 结合函数模板

template<typename R = void>
R default_value() {
if constexpr (std::is_void_v<R>) {
return; // void 返回类型不能有返回值
} else {
return R{}; // 默认构造 R 类型
}
}
int main() {
default_value(); // R = void,无返回值
int x = default_value<int>(); // R = int,返回 0(默认构造)
}
  • 当 R = void 时,函数不能返回任何值。
  • 当 R = int 时,函数返回 int{}(即 0)。

2. 常见应用场景

2.1 回调函数(Callback)的默认返回类型

template<typename R = void>
class Callback {
public:
using ReturnType = R;
virtual R execute() = 0; // 纯虚函数
};
// 特化 void 返回类型的情况
template<>
class Callback<void> {
public:
void execute() { /* 不需要返回值 */ }
};
  • 如果回调函数不需要返回值,可以使用 Callback<>(默认 void)。
  • 如果需要返回值,可以指定 Callback<int> 等。

2.2 函数对象(Functor)的默认行为

template<typename R = void>
struct Identity {
R operator()(R x) { return x; }
};
template<>
struct Identity<void> {
void operator()(auto x) { /* 不返回任何值 */ }
};
int main() {
Identity<int> id_int;
int a = id_int(42); // 返回 42
Identity<> id_void;
id_void(42); // 无返回值
}
  • Identity<int> 返回输入值。
  • Identity<>(即 Identity<void>)不返回任何值。

2.3 通用函数包装器(类似 std::function

template<typename R = void, typename... Args>
class FunctionWrapper {
public:
virtual R invoke(Args... args) = 0;
};
// 特化 void 返回类型
template<typename... Args>
class FunctionWrapper<void, Args...> {
public:
virtual void invoke(Args... args) = 0;
};
  • 如果 R = void,则 invoke() 不返回任何值。
  • 否则,invoke() 返回 R 类型的值。

3. 与 std::function 的对比

C++ 标准库中的 std::function 也使用了类似的技巧:

std::function<int()> func1; // 返回 int
std::function<void()> func2; // 返回 void
std::function<> func3; // 错误!必须指定返回类型
  • std::function 不能省略返回类型(必须显式指定 R)。
  • 但自定义模板可以设置默认 R = void,使 MyFunction<> 合法。

4. 总结

特性说明
template<typename R = void>定义一个默认类型为 void 的模板参数
适用场景回调函数、函数对象、通用包装器
与 void 相关的特殊处理void 不能用于返回值(如 return;)或构造(如 R{}
C++17 if constexpr 结合可以针对 void 和非 void 类型做不同处理

关键点

  1. void 是一个不完整的类型,不能直接实例化(如 void x; 非法)。
  2. void 用于函数返回类型时,表示不返回任何值
  3. 模板默认参数 可以简化代码,避免重复指定常见类型(如 void)。

这种技巧在泛型编程中非常有用,特别是需要处理“可能无返回值”的情况。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/94548.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/94548.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

国产3D大型装配设计新突破①:图纸打开设计双加速 | 中望3D 2026

本文为CAD芯智库整理&#xff0c;未经允许请勿复制、转载&#xff01;在中望3D 2026的新版中&#xff0c;不仅在设计效率上进行了重大优化&#xff0c;更是在装配方面实现了突破性的改进&#xff0c;让每一个项目都能快速、精确地从概念变为现实。 中望3D2026亮点速递装配篇将…

游戏开发状态机与行为树的优缺点

在游戏开发中&#xff0c;状态机&#xff08;Finite State Machine, FSM&#xff09; 和行为树&#xff08;Behavior Tree, BT&#xff09; 是两种常用的 AI 逻辑控制框架&#xff0c;分别适用于不同场景&#xff0c;其优缺点对比可从灵活性、维护成本、适用场景等多个维度分析…

Linux下ELF文件的介绍

目录 1.温故知新 2.ELF文件介绍 3.ELF文件组成 4.ELF文件形成到加载 5.连接过程 1.温故知新 上一篇博客&#xff0c;我们介绍了我们的动静态&#xff0c;知道了我们的库其实也是文件&#xff0c;如果我们想写一个库也是可以的&#xff0c;我们的把我们的库文件编译成.o文件…

人工智能领域、图欧科技、IMYAI智能助手2025年6月更新月报

2025年6月AI领域重要模型更新与平台优化汇总 摘要&#xff1a; 本文汇总了2025年6月期间AI领域发布的多项重要模型更新及平台功能优化信息&#xff0c;涵盖Google Gemini、阿里通义万相、字节豆包、百度文心一言、MiniMax海螺02、Google Veo3、快手可灵2.1、FLUX Kontext等模型…

从零开始学Express,理解服务器,路由于中间件

当我们初学前端时&#xff0c;常常只关注页面效果和交互&#xff0c;但随着项目复杂度提升&#xff0c;我们迟早会遇到“服务端”的问题&#xff1a;如何让一个页面的数据是从数据库来的&#xff1f;怎么让不同的用户看到不同的内容&#xff1f;这时候&#xff0c;我们就需要一…

Codeforces Round 987 (Div. 2)

ABC 略D预处理出每个位置的前缀最大和后缀最小。从后向前枚举&#xff0c;如果一个数无法后移&#xff0c;那么答案就是最大前缀&#xff0c;否则答案要不是前缀最大&#xff0c;要不就是这个数先移到前缀最大位置再移到能移到的最大的位置此处的答案。用线段树维护#include<…

Javascript/ES6+/Typescript重点内容篇——手撕(待总结)

前端核心知识点梳理与面试题详解 1. Promise 核心知识点 Promise 是异步编程的解决方案&#xff0c;用于处理异步操作三种状态&#xff1a;pending&#xff08;进行中&#xff09;、fulfilled&#xff08;已成功&#xff09;、rejected&#xff08;已失败&#xff09;状态一旦改…

[自动化Adapt] 父子事件| 冗余过滤 | SQLite | SQLAlchemy | 会话工厂 | Alembic

第五章&#xff1a;事件处理与融合 欢迎回到OpenAdapt探索之旅~ 在第四章&#xff1a;系统配置中&#xff0c;我们掌握了如何定制化系统参数。更早的第一章&#xff1a;录制引擎则展示了系统如何捕获海量原始操作数据。 假设我们需要训练机器人输入"hello"一词。原…

组合期权:跨式策略

文章目录0.简介1.买入跨式组合&#xff08;Long Straddle&#xff09;1.1 适用场景​1.2 合约选择1.3 损益分析1.4 案例示范2.卖出跨式组合&#xff08;Short Straddle&#xff09;2.1 适用场景​2.2 合约选择2.3 损益分析2.4 案例示范3.小结参考文献0.简介 跨式策略是一种交易…

Vue计算属性详解2

可写计算属性 计算属性默认是只读的,但在特殊场景下,我们可以创建"可写"的计算属性,通过同时提供getter和setter实现: <script setup>import { ref, computed } from vueconst firstName = ref(John)const lastName = ref(Doe)const fullName = computed(…

UniStorm 5.3.0 + Unity2022 + URP配置说明

一、前言 以前我用的是UniStorm3.0&#xff0c;主要用在内置管线里面&#xff0c;最近想在URP管线里面使用UniStorm天气系统&#xff0c;于是弄了UniStorm5.3.0的包&#xff0c;在Unity2022.3的URP模式下配置&#xff0c;直接导入package&#xff0c;两次宣告失败。最后看了官方…

力扣经典算法篇-44-组合总和(回溯问题)

1、题干 给你一个无重复元素的整数数组candidates和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重复被选取 。…

矩阵与高斯消元:数学算法在计算机领域的应用

一、概述和基本概念 矩阵&#xff0c;类似于在 C 中我们看到的二维数组。它有两个维度&#xff0c;行和列。下面是一个典型的矩阵&#xff1a; M[12342345445610111213] M \begin{bmatrix} 1 & 2 & 3 & 4 \\ 2 & 3 & 4 & 5 \\ 4 & 4 & 5 &…

【补题】CodeTON Round 1 (Div. 1 + Div. 2, Rated, Prizes!) D. K-good

题意&#xff1a;给一个n&#xff0c;如果能被k个数整除&#xff0c;要求这k个数%k后不相同&#xff0c;问如果可以&#xff0c;任意k是多少&#xff0c;如果不可以输出-1 思路&#xff1a; D. K-good_牛客博客 从来没见过&#xff0c;太诡异了&#xff0c;做题做少了 1.…

LLM推理框架的“权力的游戏”:vLLM之后的群雄逐鹿

既然我们已经深入探讨了本地与云端的两大代表Ollama和vLLM&#xff0c;是时候将视野拓宽&#xff0c;检视一下在高性能推理这片“高手如云”的竞技场中&#xff0c;还有哪些重量级的玩家。vLLM的出现点燃了战火&#xff0c;但远非终点。 欢迎来到LLM推理框架的“后vLLM时代”—…

TDengine IDMP 背后的技术三问:目录、标准与情景

过去十年&#xff0c;#工业 和#物联网 场景经历了快速的#数字化 建设&#xff1a;传感器接入、系统联网、数据上云……数据平台已能轻松承载每秒千万级别的写入&#xff0c;每天几 TB 的存储量。但今天再回头看&#xff0c;这些看似“完成”的系统&#xff0c;实际上只解决了一…

MyBatis基础操作完整指南

文章目录MyBatis简介环境搭建Maven依赖数据库表结构核心配置MyBatis配置文件数据库配置文件实体类基础CRUD操作Mapper接口Mapper XML映射文件工具类测试类动态SQL常用标签高级特性一对一关联映射一对多关联映射分页查询使用注解方式MyBatis简介 MyBatis是Apache的一个开源项目…

go与grpc

目录下载与安装遇到的问题cmd中protoc找不到命令cmd中--go_out: protoc-gen-go: Plugin failed with status code 1.下载与安装 下载protoc&#xff1a; https://github.com/protocolbuffers/protobuf/releases 点击下载相应电脑版本即可&#xff0c;我是windows系统下载了pro…

2025年AI面试重构招聘新生态

当企业面临业务扩张与人才竞争的双重压力&#xff0c;传统招聘模式已难以满足高效、精准、公平的人才筛选需求。尤其在校招季、蓝领用工潮等关键节点&#xff0c;面试官超负荷运转、跨地域协调困难、评估标准模糊等问题频发。AI技术的深度介入正推动招聘行业从“经验驱动”向“…

Rust进阶-part5-trait

Rust进阶[part5]_trait trait概述 在 Rust 中,trait 是一种定义共享行为的方式。它类似于其他语言中的接口,允许我们定义一组方法签名,然后让不同的类型去实现这些方法。通过 trait,我们可以实现多态性,即不同类型可以以统一的方式处理。 普通实现 使用 trait 关键字来…