首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

C++之std::is_object

  • 24-03-18 06:43
  • 4727
  • 12704
blog.csdn.net

相关系列文章

C++之std::is_object

C++之std::decay

C++模板函数重载规则细说

C++之std::declval

C++之std::move(移动语义)

C++之std::forward(完美转发)

C++之std::enable_if

C++之std::is_pod(平凡的数据)

目录

1.概述

2.原理分析

2.1.std::is_object

2.2.bool_constant

3.使用

4.总结


1.概述

std::is_object是一种C++类型特性,其用途是判断一个类型是否是一个对象类型(除了函数、引用和void类型)。如下例子:

  1. #include
  2. #include
  3. class A {};
  4. int main() {
  5. std::cout << std::boolalpha;
  6. std::cout << "is_object:" << std::endl;
  7. std::cout << "int: " << std::is_object<int>::value << std::endl; //输出:true
  8. std::cout << "A: " << std::is_object::value << std::endl; //输出:true
  9. std::cout << "A&: " << std::is_object::value << std::endl; //输出:false
  10. std::cout << "A*: " << std::is_object::value << std::endl; //输出:true
  11. std::cout << "int(int): " << std::is_object<int(int)>::value << std::endl; //输出:false
  12. std::cout << "int(*)(int): " << std::is_object<int(*)(int)>::value << std::endl; //输出:
  13. // true
  14. return 0;
  15. }

2.原理分析

2.1.std::is_object

std::is_object的源码如下:

  1. template <class _Ty>
  2. constexpr bool is_object_v = !is_function_V<_Ty> && !is_reference_v<_Ty> && !is_void_v<_Ty>;
  3. template <class _Ty>
  4. struct is_object : bool_constant> {};

is_function_v : 判断是否检查 T 是否为函数类型。如 std::function 、 lambda 、有重载 operator() 的类和指向函数指针不是函数类型。若 T 为函数类型,则提供等于 true 的成员常量 value 。否则, value 等于 false, 示例如下:

  1. #include
  2. using namespace std;
  3. struct GeeksforGeeks {
  4. int func() const&;
  5. };
  6. template <typename>
  7. struct Computer {
  8. };
  9. template <class A, class B>
  10. struct Computer {
  11. using member_type = B;
  12. };
  13. int x1();
  14. int main()
  15. {
  16. cout << is_function<int(int)>::value << endl; //输出:true
  17. cout << is_function::value << endl; //输出:false
  18. cout << is_function<int>::value << endl; //输出:false
  19. cout << is_function<decltype(x1)>::value << endl; //输出:true
  20. using A = Computer<decltype(
  21. &GeeksforGeeks::func)>::member_type;
  22. cout << is_function::value << endl; //输出:true
  23. return 0;
  24. }

is_reference_v : 若 T 是引用类型(左值引用或右值引用),则提供等于 true 的成员常量 value 。对于任何其他类型, value 为 false; 示例如下:

  1. #include
  2. #include
  3. using namespace std;
  4. class MyTest {
  5. };
  6. int main() {
  7. cout << "\n class TP : "<::value; //输出:false
  8. cout << "\n class TP&: "<::value; //输出:true
  9. cout << "\n class TP&&: "<::value; //输出:true
  10. return 0;
  11. }

is_void_v : ​检查 T 是否为 void 类型。若 T 是类型 void 、 const void 、 volatile void 或 const volatile void ,则提供等于 true 的成员常量 value。否则, value 等于 false; 示例如下:

  1. #include
  2. #include
  3. int main()
  4. {
  5. std::cout << std::boolalpha;
  6. std::cout << std::is_void<void>::value << '\n'; //输出:true
  7. std::cout << std::is_void<int>::value << '\n'; //输出:false
  8. }

2.2.bool_constant

bool_constant是integral_constant的别名,从下面的定义可以看出:

  1. template <bool _Val>
  2. using bool_constant = integral_constant<bool, _Val>;
  3. using true_type = bool_constant<true>;
  4. using false_type = bool_constant<false>;

那么integral_constant的定义呢?继续看下面:

  1. template <class _Ty, _Ty _Val>
  2. struct integral_constant {
  3. static constexpr _Ty value = _Val;
  4. using value_type = _Ty;
  5. using type = integral_constant;
  6. constexpr operator value_type() const noexcept {
  7. return value;
  8. }
  9. _NODISCARD constexpr value_type operator()() const noexcept {
  10. return value;
  11. }
  12. };

        std::integral_constant包装特定类型的静态常量,它是C++类型特征的基类。我们可以看到,这个模板类接受两个参数,一个类型_Ty和一个该类型的值_Val。它提供了一个静态的常量成员value,该成员的值就是传入的_Val;其中,using value_type = _Ty;和using type       = integral_constant;分别用来定义value的类型以及integral_constant本身的类型。

        然后,它还提供了两个转换函数,一个是constexpr operator value_type() const noexcept,可以将std::integral_constant对象隐式转换为T类型的值;另一个是constexpr value_type operator()() const noexcept,可以将std::integral_constant对象当作函数来调用,并返回其内部保存的常量。

        std::integral_constant 的两个最常用的特化版本是 std::true_type 和 std::false_type。它们是 std::integral_constant 的特化版本,其中 std::true_type 是 std::integral_constant,std::false_type 是 std::integral_constant。这两种类型的主要用途是表示编译期的布尔值。在模板元编程中,它们常被用来代表一种编译期的"是"和"否",从而允许我们进行编译期的条件判断。同时,由于它们都是类型,因此也可以作为类型标签来使用,帮助我们在模板元编程中传递信息。

        通过这样的设计,std::integral_constant能够让我们在编译期间就能确定某些值,从而提高代码的效率。同时,因为它包含了值类型的信息,我们还可以根据这个信息进行编程,提高代码的灵活性。

        通过上述的解释和分析,我们可以很清楚的理解了std::is_object的含义了。

3.使用

std::is_object主要用于元编程中的类型检查,以便在编译时确定某个类型是否符合限制条件。使用方法也比较简单,只需在代码中调用std::is_object<>模板,并传入要检查的类型名,即可获得该类型是否为对象类型的结果。示例如下:

  1. template <typename T>
  2. void calc(){
  3. static_assert(std::is_object::value, "T must be an object type.");
  4. //...
  5. }
  6. class MyTest{};
  7. int main(){
  8. calc<int>();
  9. MyTest x;
  10. func<decltype(x)>();
  11. calc<int&>(); //compile error
  12. return 0;
  13. }

上述代码中,定义了一个模板函数calc,该函数要求其参数类型必须是对象类型。在模板函数中使用了std::is_object<>模板,来检查模板参数类型是否为对象类型。如果不是,将会抛出一个编译器错误。这样,就能够在编译期间检测到错误的使用,减少运行时错误的概率。

使用注意:1)std::is_object判断的是类型是否为对象类型,而非是否为类类型或枚举类型。  2)使用std::is_object模板时,需要注意传入的类型名中不要包含已删除的引用和cv限定符。示例如下:

  1. #include
  2. #include
  3. struct MyStruct{};
  4. enum class MyEnum{A,B};
  5. int main(){
  6. std::cout << std::is_object::value << std::endl; //true
  7. std::cout << std::is_object::value << std::endl; //true
  8. std::cout << std::is_object<int>::value << std::endl; //true
  9. std::cout << std::is_object<const int>::value << std::endl; //true
  10. std::cout << std::is_object<const int&>::value << std::endl; //false
  11. std::cout << std::is_object<const volatile int>::value << std::endl; //true
  12. return 0;
  13. }

4.总结

std::is_object是一个用于元编程的C++类型特性,用于判断一个类型是否是对象类型。只需在代码中调用std::is_object<>模板,并传入要检查的类型名,即可判断该类型是否为对象类型。在编写代码时,需要注意std::is_object判断的是类型是否为对象类型,而不是类类型或枚举类型。同时,在使用std::is_object模板进行类型检查时,需要注意传入的类型名中不要包含已删除的引用和cv限定符。通过合理使用std::is_object模板,可以在编译期间检测到错误的使用,减少运行时错误的概率,提高代码稳定性。

注:本文转载自blog.csdn.net的流星雨爱编程的文章"https://blog.csdn.net/haokan123456789/article/details/135619893"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top