C99 facilitates support designated initializers:
struct XYZ { int x,y,z; }; static const struct XYZ zyx = { .z = 1, .y = 2, .x = 3 }; static const struct XYZ yxz = { y : 1, x : 2, z : 3 };
I found this handy feature very useful, since it does not require remembering order of the struct fields and simplifies refactoring and/or evolving of the existing code.
C++0X and C++1X does not allow this (please follow this link for more details)
This page has inspired me on a practical solution to this problem.
The solution is in templetization of the structure and providing ad-hoc template specialization constructor:
template<int N> struct XYZ { int x,y,z; inline XYZ() {} // fall-back constructor implementation }; template<>inline XYZ<1>::XYZ() : z(1), y(2), x(3) {} static XYZ<1> zyx; static const int a = 1, b = 2, c = 3; template<>inline XYZ<2>::XYZ() : x(a), z(b), y(c) {} // Not possible in C99 static XYZ<2> xzy;
Compiler may complain about wrong order of initialization, but that the intent is.
GCC can be instructed to ignore this error with a pragma:
#pragma GCC diagnostic ignored "-Wreorder"
This approach, however, disables struct initialization with brace enclosed lists:
static XYZ<0> xyz = { 1, 2, 3}; // Does not compile
The struct XYZ now have a constructor and is not recognized as an aggregate anymore (see for definitions)
To have option for both designated and brace-encoded initializers the template can be specialized
template<> struct XYZ<0> { int x,y,z; }; static XYZ<0> xyz = { 1, 2, 3 };
Although, this kind of specialization has one drawback – definition of XYZ is now present in two variants.
Post a Comment