nanxing_static_reflect.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #ifndef _STATIC_H_
  2. #define _STATIC_H_
  3. //静态反射库(C++26提案中出现C++静态反射)
  4. //但是C++能通过一些现有的手段实现静态反射,这里尝试一下写一个C++的静态反射
  5. //验证宏的参数个数
  6. //这个也很有意思,用了64个占位符号,
  7. #define EMPTY_MACRO_CHECK(...) __VA_ARGS__ EMPTY_MACRO_CHECK_1 //用于实现判断参数个数是不是零个,如果是0个将返回一个全空的字符串
  8. #define EMPTY_MACRO_CHECK_1(...) #__VA_ARGS__
  9. #define GET_NTR_AGR( \
  10. _1,_2,_3,_4,_5,_6,_7,_8,_9,_10, \
  11. _11,_12,_13,_14,_15,_16,_17,_18, \
  12. _19,_20,_21,_22,_23,_24,_25,_26,_27,_28,_29,_30,\
  13. _31,_32,_33,_34,_35,_36,_37,_38,_39,\
  14. _40,_41,_42,_43,_44,_45,_46,_47,_48,_49,\
  15. _50,_51,_52,_53,_54,_55,_56,_57,_58,_59, \
  16. _60,_61,_62,_63,_64,n,...)n
  17. #define GET_ARG_COUNT(...) GET_NTR_AGR(__VA_ARGS__, \
  18. 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, \
  19. 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, \
  20. 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, \
  21. 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,0 ) \
  22. //接下来一个计算结构体的参数类型的泛型
  23. struct Any_type
  24. {
  25. template<typename T>
  26. operator T(); //即代表在模板中Any_type结构体可以转换为任意类型(当然,这个只能在编译期的模板中使用)
  27. //这是C++模板的一个很重要的特性,即C++在模板中不会关注这个类型能否这样进行转换,也不关注是怎么进行转换的
  28. //(这也是为什么这个函数连函数体都可以没有)
  29. //C++模板推导过程中只关注这个函数的转换的类型结果是什么
  30. //同时也可以引出另一个特性,即C++模板推导中使用一个函数的返回值作为推导依据时,同样C++也只关注返回值类型是什么
  31. //同时C++的特化是做惰性特化,在运行期不调用的函数根本不会进行特化
  32. //这也就是为什么这个函数可以存在且运行期不会报错的原因,因为C++根本没有生成这个模板函数的实例
  33. //下面就是一个例子
  34. };
  35. /******************************************
  36. * 加上第二个前置的知识SFINAE(Substitution failure is not an error)
  37. * 首先一言以蔽之,这实际上可以理解为模板的重载
  38. * 这几个词确实很抽象
  39. * 一个一个解释Substitution指的是模板匹配的过程
  40. * failure失败,歧义主要出现在这里
  41. * 在计算机程序中的失败和现实中不太一样
  42. * 看一个例子(if语句)
  43. *int a=0;
  44. *if(a==1)
  45. * a++;
  46. *if(a==0)
  47. * a--;
  48. * 首先在if(a==1)中会匹配失败(failure)
  49. * 但是会继续去匹配if(a==0)即failure is not error
  50. *
  51. *
  52. * ******************************************/
  53. // template <typename T,typename ... Args>
  54. // consteval int CountMember(Args&&... args) 等价写法
  55. template <typename T>
  56. consteval int CountMember(auto&&... Args)
  57. {
  58. if constexpr(!requires{T{Args...};})
  59. {
  60. return sizeof...(Args)-1;
  61. }
  62. else{
  63. return CountMember<T>(Args... , Any_type{}); //递归添加一个额外的参数
  64. }
  65. }
  66. #endif