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