template<typename R = void> 意义

发布于:2025-08-05 ⋅ 阅读:(12) ⋅ 点赞:(0)

在 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)。

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


网站公告

今日签到

点亮在社区的每一天
去签到