C++标准模板(STL)- 类型支持 (类型修改,对给定类型添加一层指针,std::add_pointer)

类型特性


类型特性定义一个编译时基于模板的结构,以查询或修改类型的属性。

试图特化定义于 <type_traits> 头文件的模板导致未定义行为,除了 std::common_type 可依照其所描述特化。

定义于<type_traits>头文件的模板可以用不完整类型实例化,除非另外有指定,尽管通常禁止以不完整类型实例化标准库模板。
 

类型修改

类型修改模板通过应用修改到模板参数,创建新类型定义。结果类型可以通过成员 typedef type 访问。
 

对给定类型添加一层指针

template< class T >
struct add_pointer;

(C++11 起)

T 为引用类型,则提供成员 typedef type ,其为指向被引用类型的指针。

否则,若 T 指名对象类型、无 cv 或引用限定的函数类型或(可有 cv 限定的) void 类型,则提供成员 typedef type ,其为类型 T*

否则(若 T 为 cv 或引用限定的函数类型),提供成员 typedef type ,其为类型 T

成员类型

名称 定义
type 指向 TT 所引用类型的指针

辅助类型

template< class T >
using add_pointer_t = typename add_pointer<T>::type;

(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

猜你喜欢

转载自blog.csdn.net/qq_40788199/article/details/134543511