C++模板元编程(6)模板参数替换(Template argument substitution)

news/2024/11/16 22:20:03/

文章目录

    • 1、什么是模板参数替换
    • 2、实例
    • 3、模板参数替换规则

1、什么是模板参数替换

模板参数替换(Template argument substitution):在函数模板实例化的过程中,模板参数会被替换为实际的参数类型或值。这个替换过程称为模板参数替换。它发生在编译时,根据函数调用时传递的实际参数类型或值来替换函数模板中的模板参数。

注意和模板参数推导这个概念区分开来。

模板参数推导(Template argument deduction):当我们调用一个函数模板时,编译器会尝试推导出模板参数的具体类型。这个推导过程称为模板参数推导。它使编译器能够根据传递给函数的实参来自动确定模板参数的类型。

简而言之,模板参数替换是指在函数模板实例化时将模板参数替换为具体的类型或值,而模板参数推导是指在函数调用时根据实际参数自动确定模板参数的具体类型。

2、实例

以下是示例代码,展示了模板参数替换和模板参数推导的使用:

template <typename T>
void printType(T value) {std::cout << "Type: " << typeid(value).name() << std::endl;
}template <typename T>
void add(T a, T b) {T result = a + b;std::cout << "Sum: " << result << std::endl;
}int main() {printType<int>(5);// 模板参数替换:将T替换为int,生成void printType(int value)add(3, 4);// 模板参数推导:根据实际的参数类型推导出T的类型为int,生成void add(int a, int b)return 0;
}

在这个例子中,我们使用printType函数模板来打印参数的类型。通过显式实例化调用printType,我们进行了模板参数替换。

另外,我们使用add函数模板来计算两个数的和。通过使用add(3, 4)进行函数调用,编译器根据实际的参数类型推导出模板参数的具体类型为int,进行了模板参数推导。

3、模板参数替换规则

在函数模板参数替换过程中,所有数组和函数类型的函数参数都会被调整为指针,并且函数参数的顶层cv限定符会被移除(与常规函数声明相同)。

这意味着在进行函数模板参数替换后,所有数组类型的函数参数都会自动调整为指向数组元素的指针,同时,函数参数的顶层const和volatile限定符会被移除。

需要注意的是,这种移除顶层cv限定符的操作不会影响函数内部参数的类型,即在函数内部使用这些参数时,其类型仍然保持原样。

看几个例子就懂了。

例子1 顶层const、volatile被移除

理解这个概念的一个重要原因是,通过移除顶层const和volatile限定符,函数模板可以更灵活地处理各种类型的参数。

考虑以下示例:

template <typename T>
void foo(T param);int main() {const int x = 10;volatile double y = 3.14;foo(x);  // 推导出:void foo(const int param)foo(y)// 推导出:void foo(volatile double param)return 0;
}

在这个示例中,我们有一个名为foo的函数模板,它接受一个类型为T的参数。当我们调用foo并传递一个带有顶层const或volatile限定符的参数时,编译器会自动推导出对应的函数实例,但移除了顶层const和volatile修饰符。

因此,对于const int x,推导的模板参数类型为int,而不是const int。对于volatile double y,推导的模板参数类型为double,而不是volatile double。

这种行为允许函数模板具有更广泛的适用性,能够处理更多类型的参数,而不仅仅局限于带有顶层const和volatile限定符的类型。这也与常规函数声明中的参数类型推导类似,常规函数声明也会忽略参数的顶层const和volatile修饰。


http://www.ppmy.cn/news/1041631.html

相关文章

element-Plus中el-menu菜单无法正常收缩解决方案

<el-menu :collapse"true">如图所示收缩之后&#xff0c;有子级的菜单还有箭头文字显示 从代码对比看层级就不太对了&#xff0c;嵌套错误了&#xff0c;正常下方官网的ul标签下直接是li&#xff0c;在自己的代码中&#xff0c;ul标签下是div标签&#xff0c;层…

(三)行为型模式:3、解释器模式(Interpreter Pattern)(C++示例)

目录 1、解释器模式&#xff08;Interpreter Pattern&#xff09;含义 2、解释器模式的UML图学习 3、解释器模式的应用场景 4、解释器模式的优缺点 5、C实现解释器模式的实例 1、解释器模式&#xff08;Interpreter Pattern&#xff09;含义 解释器模式&#xff08;Interp…

Greenplum多级分区表添加分区报错ERROR: no partitions specified at depth 2

一般来说&#xff0c;我们二级分区表都会使用模版&#xff0c;如果没有使用模版特性&#xff0c;那么就会报ERROR: no partitions specified at depth 2类似的错误。因为没有模版&#xff0c;必须要显式指定分区。 当然我们在建表的时候&#xff0c;如果没有指定&#xff0c;那…

【eNSP】交换机(vlan和vlan间通信)

【eNSP】交换机&#xff08;vlan和vlan间通信&#xff09; 原理术语过程 实验根据图片连接模块配置设备名称和IP地址配置交换机交换机链路指定sw1配置sw2配置 设置网关交换机互联实验设置查看设置结果 ospf配置 原理 HUB集线器&#xff1a;它的作用可以简单的理解为将一些机器…

RFID技术助力汽车零配件装配产线,提升效率与准确性

随着科技的不断发展&#xff0c;越来越多的自动化设备被应用到汽车零配件装配产线中。其中&#xff0c;射频识别&#xff08;Radio Frequency Identification&#xff0c;简称RFID&#xff09;技术凭借其独特的优势&#xff0c;已经成为了这一领域的重要技术之一。本文将介绍RF…

大数据岗位秋招面试八股文总结(不定时更新)

HIVE面试题 内部表和外部表的区别 未被external修饰的是内部表&#xff0c;被external修饰的是外部表&#xff1b; 内部表数据由Hive自身管理&#xff0c;外部表由HDFS管理&#xff1b; 删除内部表会直接删除元数据及存储数据&#xff0c;删除外部表&#xff0c;仅仅会删除…

【LINUX协议栈】netfilter之filter表、mangle表、nat表、raw表

1、filter表 Filter表 是以kernel module形式加载的(insmod iptable_filter)入口在net/ipv4/netfilter/iptable_filter.c中Filter表主要在以下Hook点起作用&#xff1a; #define FILTER_VALID_HOOKS ((1 << NF_INET_LOCAL_IN) | \(1 << NF_INET_FORWARD) | \(1 &…

c语言每日一练(9)

前言&#xff1a;每日一练系列&#xff0c;每一期都包含5道选择题&#xff0c;2道编程题&#xff0c;博主会尽可能详细地进行讲解&#xff0c;令初学者也能听的清晰。每日一练系列会持续更新&#xff0c;暑假时三天之内必有一更&#xff0c;到了开学之后&#xff0c;将看学业情…