定义
traits是一种用于泛型编程(Generic Programming)技术, 允许程序根据类型特征进行编译期决策
traits可以在编译时查询和操作类型属性, 而无需在运行时进行类型检查, 通常用于模板编程中以增强代码灵活性和可重用性
例如可以创建一个traits来确定类型是否为某种类型(如整数、浮点数、指针等), 是否满足某种条件(如可复制、可移动), 或者是否具备某种操作(如算术操作、输入输出操作)等
实现
traits通常以模板类形式实现, 并使用模板特化(Template Specialization)来定义特定类型特性
is_same
std::is_same
是C++标准库中所提供traits, 用于判断两个类型是否相同
#include <iostream>
#include <type_traits>
template <typename T>
void CheckType() {
if (std::is_same<T, int>::value) {
std::cout << "type is int" << std::endl;
} else {
std::cout << "type is not int" << std::endl;
}
}
int main() {
CheckType<int>();
CheckType<double>();
return 0;
}
自定义Traits类
可以自定义traits类来检查某个类型, 通常使用模板特化来对特定类型进行处理
#include <iostream>
#include <type_traits>
// 默认情况下, 非整数类型
template <typename T>
struct IsInteger {
static const bool value = false;
};
// 针对整数类型进行特化
template <>
struct IsInteger<int> {
static const bool value = true;
};
template <>
struct IsInteger<long> {
static const bool value = true;
};
template <typename T>
void CheckIntegerType() {
if (IsInteger<T>::value) {
std::cout << "type is integer" << std::endl;
} else {
std::cout << "type is not integer" << std::endl;
}
}
int main() {
CheckIntegerType<int>();
CheckIntegerType<double>();
return 0;
}
上面代码中, 定义了一个 IsInteger traits 类
通过模板特化将 IsInteger<int>
和 IsInteger<long>
设置为 true, 而其他类型默认为 false
示例
template<class T>
typename iterator_traits<T>::value_type func(T ite) {
return *ite;
}
- 模板声明
template
- 返回类型 typename iterator_traits
::value_type
这是函数返回类型, 使用 iterator_traits 提取 T 类型所对应迭代器值类型(即 value_type)
typename 关键字用于指明 iterator_traits
- 参数 T ite
该函数接受一个类型为 T 参数 ite, 通常是一个迭代器(例如指向容器指针或迭代器)
- 函数体 return *ite;
函数返回 *ite, 即传入迭代器所指向值, 意味着 T 必须是一个可以解引用迭代器类型
iterator_traits
iterator_traits 是一个标准库模板类, 用于萃取迭代器相关类型信息
它主要定义了几个类型别名:value_type、difference_type、pointer、reference 等
iterator_traits
例如, 若 T 是 std::vector
typename 使用
在 C++ 中, typename 关键字用于消除编译器二义性, 其显式说明后面名称是一个类型(type)
由于 iterator_traits
函数用途
该函数接受一个迭代器 ite, 并返回迭代器解引用后值
返回类型是 T 所对应迭代器 value_type, 这确保了返回值类型与 ite 所指向对象类型相匹配
因此, 该函数可以处理任意迭代器, 例如 std::vecto<int>::iterator、std::list<std::string>::iterator 等, 而不需要知道具体容器类型
#include <iostream>
#include <vector>
#include <iterator>
template<class T>
typename std::iterator_traits<T>::value_type func(T ite) {
return *ite;
}
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
auto it = vec.begin();
int val = func(it);
std::cout << "The value is: " << val << std::endl;
return 0;
}