Disclaimer: I know there are a dozen better ways to implement the following, but I'm doing it as a ways of learning more about templates and pointers to members. I'm playing around with them and I want to see if the following is possible.
I want to have a non-member template function that serves to act as a non-static member function. Different classes can implement it on their own and set which data members the function affects.
template <typename T, typename Y, Y T::* P>
void add10ToMember() {
*P += static_cast<Y>(10);
}
struct DoubleHolder
{
double value{ 0.0 };
void(&add10)(void) =
add10ToMember<DoubleHolder, double, &DoubleHolder::value>;
};
struct IntHolder
{
int value{ 0 };
void(&add10)(void) =
add10ToMember<IntHolder, int, &IntHolder::value>;
};
In the example I have made the template function add10ToMember, a simple function that adds 10 to the given member.
As soon as I instantiate an object of DoubleHolder or IntHolder, compilation fails and the errors I get are: "'*': illegal on operands of type 'int IntHolder::* '", "'+=': illegal, left operand has type 'int IntHolder::* '".
I understand why I'm getting the error: add10ToMember doesn't actually know which DoubleHolder or IntHolder it should perform the operation on. add10ToMember<IntHolder, int, &IntHolder::value> doesn't become an actual member function; it's still just a global function that has effect on a non-given IntHolder instance.
But I just don't get what the right way to write what I want would be then, if not this. Is it even possible?