类型特性
类型特性定义一个编译时基于模板的结构,以查询或修改类型的属性。
试图特化定义于 <type_traits> 头文件的模板导致未定义行为,除了 std::common_type 可依照其所描述特化。
定义于<type_traits>头文件的模板可以用不完整类型实例化,除非另外有指定,尽管通常禁止以不完整类型实例化标准库模板。
类型修改
类型修改模板通过应用修改到模板参数,创建新类型定义。结果类型可以通过成员 typedef type 访问。
对给定类型添加一层指针
template< class T > |
(C++11 起) |
若 T
为引用类型,则提供成员 typedef type
,其为指向被引用类型的指针。
否则,若 T 指名对象类型、无 cv 或引用限定的函数类型或(可有 cv 限定的) void 类型,则提供成员 typedef type
,其为类型 T*
。
否则(若 T 为 cv 或引用限定的函数类型),提供成员 typedef type
,其为类型 T
。
成员类型
名称 | 定义 |
type |
指向 T 或 T 所引用类型的指针 |
辅助类型
template< class T > |
(C++14 起) |
可能的实现
namespace detail
{
template <class T>
struct type_identity
{
using type = T;
}; // 或使用 std::type_identity (C++20 起)
template <class T>
auto try_add_pointer(int) -> type_identity<typename std::remove_reference<T>::type*>;
template <class T>
auto try_add_pointer(...) -> type_identity<T>;
} // namespace detail
template <class T>
struct add_pointer : decltype(detail::try_add_pointer<T>(0)) {};
调用示例
#include <iostream>
#include <type_traits>
int main()
{
int i = 123;
int& ri = i;
typedef std::add_pointer<decltype(i)>::type IntPtr;
typedef std::add_pointer<decltype(ri)>::type IntPtr2;
IntPtr pi = &i;
std::cout << "i = " << i << std::endl;
std::cout << "*pi = " << *pi << std::endl;
std::cout << "std::is_pointer<std::add_pointer<decltype(i)>::type>::value: "
<< std::is_pointer<IntPtr>::value << std::endl;
std::cout << "std::is_same<std::add_pointer<decltype(i), int*>::value: "
<< std::is_same<IntPtr, int*>::value << std::endl;
std::cout << "std::is_same<std::add_pointer<IntPtr2, IntPtr>::value: "
<< std::is_same<IntPtr2, IntPtr>::value << std::endl;
std::cout << std::endl;
typedef std::remove_pointer<IntPtr>::type IntAgain;
IntAgain j = i;
std::cout << "j = " << j << std::endl;
std::cout << "std::is_pointer<std::remove_pointer<IntPtr>::type>::value: "
<< std::is_pointer<std::remove_pointer<IntPtr>::type>::value << std::endl;
std::cout << "std::is_pointer<std::remove_pointer<IntPtr>::type>::value: "
<< std::is_same<IntAgain, int>::value << std::endl;
return 0;
}
输出
i = 123
*pi = 123
std::is_pointer<std::add_pointer<decltype(i)>::type>::value: 1
std::is_same<std::add_pointer<decltype(i), int*>::value: 1
std::is_same<std::add_pointer<IntPtr2, IntPtr>::value: 1
j = 123
std::is_pointer<std::remove_pointer<IntPtr>::type>::value: 0
std::is_pointer<std::remove_pointer<IntPtr>::type>::value: 1