C++用模板函数匹配内置数组

用函数模板匹配内置数组

这是我在看《程序设计原理与实践(第二版)(进阶篇)》中学习Matrix库相关内容的时候看到的一个知识点。

#include<iostream>
using namespace std;
template<class T, int n>
void test(const T(&a)[n]) {     //这是一个重点:数组的引用。这是C++才有的特性,C中没有
								// (&a) 这里的括号是必须有的。
	for (int i = 0; i < n; i++)
		cout << a[i] << '\t';
	cout << endl;
}

int main() {
	int a[]{ 1,2,3,4,5 }; 		//编译器能够推断出已经初始化的数组的规模
	test(a);

	return 0;
}

数组知识补充:
数组有两个特性,主要在需要用数组作为参数传递时体现:一是不能复制数组;二是使用数组名时,数组名就相当于指向数组的第一个元素的指针(实际就是这样)。因为不能复制,所以无法编写使用数组类型的形参,数组会自动转化为指针

#include<iostream>
using namespace std;
void test(int a[5]) {		//自动转化为指向第一个元素的指针
	*a = 11;
	cout << a[0] << endl;	//输出11
}

int main() {
	int a[]{ 1,2,3,4,5 };
	test(a);
	cout << a[0] << endl;	//输出11

	return 0;
}
### C++ 模板函数的隐式类型推导规则 C++模板函数的隐式类型推导是一种强大的机制,允许编译器自动推导模板参数的具体类型。以下是关于隐式类型推导的一些重要规则: #### 1. 基本类型匹配 当传递给模板函数的实际参数是一个基本数据类型的变量时,模板会尝试将其与形参进行精确匹配。如果实际参数是 `int` 类型,则模板中的 `T` 将被推导为 `int`。 ```cpp template<typename T> void myfunc(T param) { std::cout << "T is: " << typeid(T).name() << std::endl; } myfunc(42); // 输出:T 是 int[^1] ``` #### 2. 引用和常量修饰符的影响 对于带有引用或常量修饰符的模板参数,编译器会在推导过程中保留这些修饰符。例如,在调用 `myfunc(j)` 时,由于传入的是一个 `const int` 变量,因此模板参数 `T` 被推导为 `int`,而形参 `param` 的具体类型则是 `const int&`。 ```cpp const int j = 20; template<typename T> void myfunc(const T& param) {} myfunc(j); // T 推导为 int, param 类型为 const int& ``` #### 3. 数组退化为指针 当数组作为实参传递到模板函数中时,默认情况下会被退化为指向其第一个元素的指针。这意味着模板参数不会保持原始数组的形式。 ```cpp template<typename T> void myfunc(T param) {} int arr[5]; myfunc(arr); // T 被推导为 int*, 不再是 int[5][^2] ``` #### 4. 多个参数的情况 在涉及多个模板参数的情况下,每个参数都会独立地参与类型推导过程。然而需要注意的是,所有模板参数之间必须能够形成一致的关系才能成功完成推导。 ```cpp template<class T> void func(T a, T b){ a = b; // 编译器期望两个参数具有相同的类型 } ``` 上述代码片段表明只有当两者均为相同类型或者可以相互赋值转换的时候才可以通过编译测试。 #### 5. 自动类型转换的应用场景限制 尽管存在一些内置类型的隐式转换(如从较小整数类型向较大整数类型的提升),但在大多数情形下,这种行为并不适用于复杂的数据结构或是用户自定义类对象间的关系判定上。 --- ### 示例代码展示 下面通过一段综合性的例子来进一步说明以上提到的各种情况: ```cpp #include <iostream> #include <typeinfo> // 定义通用打印函数 template<typename T> void printType(const T& value) { std::cout << "Value type: " << typeid(value).name() << "\n"; std::cout << "Template parameter T: " << typeid(T).name() << "\n\n"; } int main(){ int i = 10; double d = 3.14; // 测试基础数值类型 printType(i); printType(d); // 测试带 cv-qualifiers 和 references 的情况 const int ci = 20; printType(ci); return 0; } ``` 此程序展示了不同类型输入如何影响最终所得到的结果以及它们各自对应的内部实现细节差异之处。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值