写点什么

C++--- 类型萃取 ---is_void && is_null_pointer

作者:桑榆
  • 2022-11-24
    广东
  • 本文字数:1321 字

    阅读完需:约 4 分钟

背景

定义在<type_traits>中,用于判断一个类型是否是 void 类型,是否是 nullptr_t 类型,属于基础的类型判断。

代码实现

gcc 官网:https://gcc.gnu.org/

gcc 代码下载:https://mirrors.tuna.tsinghua.edu.cn/help/gcc.git/

gcc 版本代码:gcc-7.5.0(branch 分支)

文件位置:gcc/libstdc++-v3/include/std/type_traits

注意:以下的代码实现省略了一些宏定义部分,实际的代码还是参考 gcc 源码,这里仅用作相关原理分析。

实现分析

is_void

  template<typename>    struct __is_void_helper    : public false_type { }; 
template<> struct __is_void_helper<void> : public true_type { };
/// is_void template<typename _Tp> struct is_void : public __is_void_helper<typename remove_cv<_Tp>::type>::type { };
复制代码

这里创建了一个__is_void_helper 的辅助类,它的一般版本继承 false_type(里面的 value 值为默认的 false 值),特化版本接受 void 参数,继承 true_type(value 值默认为 true 值),这就是模板的魅力,通过特化版本直接将 void 类型识别出来。最后在正式版本中,需要对输入的类型做 remove_cv 处理,去除掉 const 和 volatile 属性,然后再与 void 进行比较。

is_null_pointer

  template<typename>    struct __is_null_pointer_helper    : public false_type { };
template<> struct __is_null_pointer_helper<std::nullptr_t> : public true_type { };
/// is_null_pointer (LWG 2247). template<typename _Tp> struct is_null_pointer : public __is_null_pointer_helper<typename remove_cv<_Tp>::type>::type { };
复制代码

这里的判断方式与 is_void 是类似的,也是使用了一个模板特化版本,如果类型为 std::nullptr_t,则直接继承 true_type。同样的也是要使用 remove_cv 去除 const 和 volatile 属性。

使用案例

#include <iostream>#include <type_traits>
int main(){
std::cout << std::boolalpha; std::cout << "int:\t" << std::is_void<int>::value << std::endl; std::cout << "void:\t" << std::is_void<void>::value << std::endl;
std::cout << "nullptr is null_pointer:\t" << std::is_null_pointer<decltype(nullptr)>::value << std::endl; std::cout << "int* is null_pointer:\t" << std::is_null_pointer<int*>::value << std::endl;
std::cout << "nullptr is pointer:\t" << std::is_pointer<decltype(nullptr)>::value << std::endl; std::cout << "int* is pointer:\t" << std::is_pointer<int*>::value << std::endl; return 0;}
复制代码

注意,上面的案例中,我们还检查了 nullptr 的类型 std::nullptr_t 是否是空指针,答案是 true,但它并不是一个指针,因为在 STL 中 nullptr_t 实际上是一个类的定义,可以指向空指针,并不是一个指针类型,所以在判断它是否是指针时,会返回 false。

总结

is_void 和 is_null_pointer 分别用来判断一个类型是否是 void 或 std::nullptr_t 类型,均使用了模板特化的方法来实现,需要注意到 std::nullptr_t 是空指针类型,但却不是指针类型,因为它是 STL 的类实现。

发布于: 刚刚阅读数: 6
用户头像

桑榆

关注

北海虽赊,扶摇可接;东隅已逝,桑榆非晚! 2020-02-29 加入

Android手机厂商-相机软件系统工程师 爬山/徒步/Coding

评论

发布
暂无评论
C++--- 类型萃取 ---is_void && is_null_pointer_C++ STL_桑榆_InfoQ写作社区