推荐答案
// www.javascriptcn.com code example
#include <iostream>
#include <type_traits>
// 使用 enable_if 实现编译时分派
template <typename T>
typename std::enable_if<std::is_integral<T>::value, void>::type
process(T value) {
std::cout << "Processing integral type: " << value << std::endl;
}
template <typename T>
typename std::enable_if<std::is_floating_point<T>::value, void>::type
process(T value) {
std::cout << "Processing floating point type: " << value << std::endl;
}
// 使用 tag dispatch 实现编译时分派
struct IntegralTag {};
struct FloatingPointTag {};
template <typename T>
void process_impl(T value, IntegralTag) {
std::cout << "Processing integral type: " << value << std::endl;
}
template <typename T>
void process_impl(T value, FloatingPointTag) {
std::cout << "Processing floating point type: " << value << std::endl;
}
template <typename T>
void process_dispatch(T value) {
if constexpr (std::is_integral_v<T>) {
process_impl(value, IntegralTag{});
} else if constexpr (std::is_floating_point_v<T>) {
process_impl(value, FloatingPointTag{});
}
}
int main() {
process(42); // 输出: Processing integral type: 42
process(3.14); // 输出: Processing floating point type: 3.14
process_dispatch(42); // 输出: Processing integral type: 42
process_dispatch(3.14); // 输出: Processing floating point type: 3.14
return 0;
}本题详细解读
enable_if 实现编译时分派
std::enable_if 是 C++ 标准库中的一个模板工具,用于在编译时根据条件启用或禁用特定的函数模板。它的基本用法是通过 std::enable_if<Condition, T>::type 来定义一个类型,如果 Condition 为 true,则 type 为 T,否则该模板将被禁用。
在上面的代码中,我们定义了两个 process 函数模板,分别用于处理整数类型和浮点类型。通过 std::enable_if 和 std::is_integral、std::is_floating_point 类型特征,编译器会根据传入的参数类型选择正确的函数模板进行实例化。
tag dispatch 实现编译时分派
tag dispatch 是一种通过传递不同的标签类型来实现编译时分派的技术。标签类型通常是空的结构体,用于在编译时区分不同的函数重载。
在上面的代码中,我们定义了两个标签类型 IntegralTag 和 FloatingPointTag,并分别实现了两个 process_impl 函数模板。在 process_dispatch 函数中,我们使用 if constexpr 和 std::is_integral_v、std::is_floating_point_v 来根据传入的参数类型选择正确的标签类型,并调用相应的 process_impl 函数。
总结
enable_if通过条件编译实现函数模板的分派。tag dispatch通过传递不同的标签类型实现函数重载的分派。- 两种方法都可以在编译时根据类型选择正确的函数实现,但
tag dispatch通常更具可读性和扩展性。