C++/CLI Pointer to Member
-
13-09-2019 - |
Question
What are the various options to implement a pointer-to-member construct in C++/CLI?
I have implemented some 2D geometry algorithms which perform some actions based on X and Y co-ordinates. I find that I am frequently duplicating code once for the X-axis and once for the Y-axis. An example is finding the maximum and minimum bounds along each axis.
Had I been using native C++, I could have used a pointer to the X or Y member (also width, height and so on) and passed it in as a parameter so that I need implement each algorithm only once. But with C++/CLI, this is not possible. What are my options? I am looking for something efficient, light-weight and terse.
Solution
I'd make the argument a template type argument instead, and use functors that encapsulate property access. E.g.:
ref class Point {
property int X;
property int Y;
};
struct Point_X_accessor
{
static int get(Point^ p) { return p->X; }
static int set(Point^ p, int value) { p->X = value; }
};
struct Point_Y_accessor
{
static int get(Point^ p) { return p->Y; }
static int set(Point^ p, int value) { p->Y = value; }
};
template <class PointAccessor>
int some_algorithm(Point^ p) { ... }
some_algorithm<Point_X_accessor>(p);
some_algorithm<Point_Y_accessor>(p);
Of course, this only makes sense if you have sufficiently many sufficiently lengthy algorithms to justify all the boilerplate. Though the wrappers could be both generated and referenced via a macro, cutting down on lines of code quite a bit.
OTHER TIPS
Option 1: if X and Y are exposed as public members, you could define them as part of an anonymous union, e.g:
class Shape {
public:
union {
struct { double X; double Y; };
double point[2];
};
...
};
This lets you access X as either shape.X or shape.point[0], and similarly, shape.Y as shape.point[1].
Option 2: If X and Y are exposed as properties, you could have their getters/setters access a member array of two elements, and then expose the array as a read-only property too. While the caller can't modify the array property, it can still modify its elements.
Option 3: well, not an option, really. Don't use .NET reflection to access the properties by name. The runtime cost is way too high.