使用C++模板判断类型的两种情形

本文介绍了两种实用的C++模板技巧:一是如何通过模板元编程判断两个输入模板类型是否相同;二是如何判断输入模板类型是否为指定类型,如double型。通过简单的代码示例展示了这些技巧的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作者:朱金灿
来源:http://blog.youkuaiyun.com/clever101


  在使用模板时经常会碰到两种需求:一种是判断输入的两个模板类型是否一样,另一种情况是判断输入的模板类型是否为指定的类型。从网上找了些资料,实现了这两种需求。

  首先是实现判断输入的两个模板类型是否一样,代码很简单:

//利用 c++模板 类型 推导思想,实现最简单的 判断两个类型 是否一样的 方法
template<typename T1, typename T2>
struct is__same
{
	operator bool()
	{
		return false;
	}
};


template<typename T1>
struct is__same<T1, T1>
{
	operator bool()
	{
		return true;
	}
};

int main(int argc, char ** argv)
{
	std::cout << is__same<int, char>() << endl;
	std::cout << is__same<short int, short int>() << endl;

	getchar();
	return 0;
}

其次是判断输入的模板类型是否为指定的类型,代码也很简单:

// 使用偏特化判断模板是否为指定类型,这里用于判断模板类型是否为double型
template <typename T>
struct is_double
{
	operator bool()
	{
		return false;
	}
};

template <>
struct is_double<double>
{
	operator bool()
	{
		return true;
	}
};

int main(int argc, char ** argv)
{

	if (!is_double<int>())
		std::cout << "this is not double type" << std::endl;

	if (is_double<double>())
		std::cout << "this is double type" << std::endl;

	getchar();
	return 0;
}

参考文献:

1. 利用 c++模板 类型 推导思想,实现最简单的 判断两个类型 是否一样的方法

2. 有没有方法判断模板函数里参数的类型?

### 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
发出的红包

打赏作者

clever101

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值