Another use for metaprogramming is when you want to have multiple typedef for variable parameters. An example of this is say you have a Vector class and we want typdef it for various dimensions and various data types.
template<int NUM_DIMENSIONS, class DataType> struct Vector { DataType m_data[NUM_DIMENSIONS; }; typedef Vector<2, int> Vector2i; typedef Vector<2, double> Vector2d; typedef Vector<2, float> Vector2f; typedef Vector<3, int> Vector3i; typedef Vector<3, double> Vector3d; typedef Vector<3, float> Vector3f;
Suppose we wanted to expand this for more dimensions and data types as well. We can make use of pattern matching and FOR_EACH_2D to make our life easier.
// Pattern match PREFIX so that we can get a prefix if appropriate // Otherwise return the type itself #define PREFIX_int EXISTS(i) #define PREFIX_float EXISTS(f) #define PREFIX_double EXISTS(d) #define GET_PREFIX(type) TRY_EXTRACT_EXISTS(CAT(PREFIX_, type), type) #define DEFINE_VECTOR_TYPE(n, type) \ typedef Vector<n, type> CAT(CAT(Vector, n), GET_PREFIX(type)); FOR_EACH_2D(DEFINE_VECTOR_TYPE, (2, 3, 4), (int, double, float)) /* Expands to typedef Vector<2, int> Vector2i; typedef Vector<2, double> Vector2d; typedef Vector<2, float> Vector2f; typedef Vector<3, int> Vector3i; typedef Vector<3, double> Vector3d; typedef Vector<3, float> Vector3f; typedef Vector<4, int> Vector4i; typedef Vector<4, double> Vector4d; typedef Vector<4, float> Vector4f; */ #undef DEFINE_VECTOR_TYPE