Typically the purpose of an adapter is to make function calls in a modified format. Is there any way to do the same sort of thing for member variables? That is, say I have an object that contains a SomePoint
and another object that contains a DifferentPoint
. SomePoint
stores it's data as member variables capitalized X
and Y
where AnotherPoint
stores it's data as member variables lowercase x
and x
. So the problem is that you can't write a function that accepts either a SomePoint
or a DifferentPoint
because you can't access .x
or .X
(even using templates without specializing entirely for each different point type, in which case you might as well just overload on the point type).
The question is is there a way to make an adapter that will produce .X
for a SomePoint
when .x
is requested? Both of these point types are library classes, so I can't edit the internals of either one directly. I would also like to avoid copying the data.
The usual way to do this is to write a traits class to specify how to get out the data you want.
Here's a possible implementation using pointer-to-members. You could make them into functions or lambdas if you would rather.
template <typename T>
struct PointTraits;
template <>
struct PointTraits<SomePoint> {
constexpr static auto getX = &SomePoint::x;
constexpr static auto getY = &SomePoint::y;
};
template <>
struct PointTraits<AnotherPoint> {
constexpr static auto getX = &AnotherPoint::X;
constexpr static auto getY = &AnotherPoint::Y;
};
Then you would use it like this:
template <typename PointT>
void printX (const PointT& point) {
std::cout << point.*PointTraits<T>::getX;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With