当前位置: 首页 > article >正文

c++元编程

元编程

编译期执行的变成,类似宏定义和模板,再编译期需要展开实现

宏定义

#define ARG_COUNTX(…) A1X(VA_ARGS)
#define A3X(x) x //使宏定义在同一级展开
#define A1X(…) A3X(A4X(VA_ARGS, 3, 2, 1, 0))
#define A4X(1, 2, 3, count, …) count

A4X最大3个元素计数的宏定义

typedef struct{int a;int b;int c;}A;
#define PREPARE_MACRO(x)     x  //必须要加,否则__VA_ARGS__展开找不到对应项
#define FIELD_RECORD_INIT() std::vector<size_t> m_FieldOffset;
#define OFFSET(TYPE,MEMBER)  ((size_t)(&(((TYPE*)0)->MEMBER)))
#define POINT_OFFSET_1(TYPE,MEMBER,...) m_FieldOffset.emplace_back(OFFSET(TYPE,MEMBER));
#define POINT_OFFSET_2(TYPE,MEMBER,...) POINT_OFFSET_1(TYPE,MEMBER) PREPARE_MACRO(POINT_OFFSET_1(TYPE,__VA_ARGS__))
#define POINT_OFFSET_3(TYPE,MEMBER,...) POINT_OFFSET_1(TYPE,MEMBER) PREPARE_MACRO(POINT_OFFSET_2(TYPE,__VA_ARGS__))
#define REGISTER_OFFSET(TYPE,...) FIELD_RECORD_INIT() PREPARE_MACRO(POINT_OFFSET_3(TYPE,__VA_ARGS__))

REGISTER_OFFSET(A,a,b,c)//遍历A的成员地址
  • for循环

宏定义循环可以通过,类似上面的宏递归展开方式实现

模板元编程

template <typename R, typename... T>    //R返回值,T参数列表
class dllfunctor_stdcall {
public:
	dllfunctor_stdcall(string dll, string function)
	{
		_f = (R(__stdcall *)(T...))DLLMap::getInstance().getProcAddress(dll, function.c_str());
	}
	R operator()(T... args) { return _f(args...); }

private:
	R(__stdcall *_f)(T...);
};

模板T,可以对应多参数函数,可以强转函数类型


template <typename T>
void fun(const T& t){
	cout << t << '\n';
}
 
template <typename T, typename ... Args>
void fun(const T& t, Args ... args){
	cout << t << ',';
	fun(args...);//递归解决(函数名相同,参数不同),利用模板推导机制,每次取出第一个,缩短参数包的大小。
}

参数展开,args…或者{args,…}

  • for循环
template <int I, int Max, typename Func>
struct ForLoop {
  static void run(Func func) {
    func(I);
    ForLoop<I + 1, Max, Func>::run(func); // 递归调用
  }
};
template <int Max, typename Func>
struct ForLoop<Max, Max, Func> {
  static void run(Func func) {}
};
ForLoop<0, 10, [](int i)>::run([](int i){std::cout << i << std::endl;});
  • if条件判断

if constexpr,常量表达式


http://www.kler.cn/a/15171.html

相关文章:

  • C++AVL平衡树
  • 软件测试基础三十 (Python + Flask实现Mock平台搭建)
  • 【python】机器学习调参与自动化:使用Hyperopt优化你的模型
  • kubernetes如何配置默认存储
  • Java通过calcite实时读取kafka中的数据
  • ChromeDriver驱动下载地址更新(保持最新最全)
  • Maven 如何下载依赖包的源码包
  • 2023年第二十届五一数学建模竞赛题目 C题详细思路
  • [最小距离的最大值] 跳石头
  • node(express框架)连接mysql 基础篇
  • 数据结构——求二叉树的属性
  • 制造策略 ETO、MTO、ATO、MTS
  • 09 【Sass语法介绍-函数指令】
  • 原理这就是索引下推呀
  • ChatGPT能让智能客服更上一层楼么?
  • Mac 地址与 IP 地址有什么区别?
  • RocketMQ第二节(安装和模块详解)
  • TCP分岔:优化云服务的性能
  • 入局生成式AI,看好亚马逊(AMZN)中期表现
  • Superset整合keycloak系统
  • linux平台移植qt
  • 浅谈欧拉定理及其扩展
  • 重写Qt中的Widget移动事件
  • 大好河山集团董事长黄国林受邀出席2023中国好公司高峰论坛暨产学研合作峰会
  • 快速理解哈希(Hash)表的运作原理
  • C++语言亚马逊国际获取AMAZON商品详情 API接口(