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 constexpr、定数式

おすすめ

転載: blog.csdn.net/daoer_sofu/article/details/130381994