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

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.lryc.cn/news/609152.html

相关文章:

  • 【Python练习】075. 编写一个函数,实现简单的语音识别功能
  • golang的包和闭包
  • slice() 和 splice()
  • 决策树模型知识点整理:从原理到实战(含可视化与调参)
  • Corrosion2靶机练习笔记
  • 【图像处理基石】如何使用deepseek进行图像质量的分析?
  • 【Django】-9- 单元测试和集成测试(上)
  • Day23--回溯--39. 组合总和,40. 组合总和 II,131. 分割回文串
  • 机器人抓取流程介绍与实现——机器人抓取系统基础系列(七)
  • 深度学习中卷积与互相关
  • [ java Thread 线程 ] 由“一对一“到“一对多“
  • 【Linux网络编程基础--socket地址API】
  • 使用 Vuepress + GitHub Pages 搭建项目文档
  • GraphRAG:基于知识图谱的检索增强生成技术解析
  • 微分方程模型:用“变化率”的语言,描绘世间万物的动态演化
  • async/await和Promise之间的关系是什么?(补充)
  • 图像识别区分指定物品与其他物体
  • SelectDB数据库,新一代实时数据仓库的全面解析与应用
  • Kubernetes滚动更新、蓝绿部署与金丝雀发布方案对比分析及选型建议
  • 延迟任务方案-DelayQueue
  • noob靶机复现笔记
  • 【stm32】GPIO输入
  • 环绕字符串中的唯一子字符串-动态规划
  • 其它IO函数
  • STM32 串口发送
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘scikit-learn’问题
  • Linux环境下使用Docker搭建多服务环境
  • 学习游戏制作记录(实现克隆攻击的克隆复制和水晶代替克隆)8.3
  • 【gradle】插件那些事
  • 7.28-8.3周报