I would like to allow the compiler to do as many optimizations at compile-time as possible. So, as far as I know, passing the member pointer as a template argument like in the following code block would be the best way:
struct obj {
double x;
};
template <auto member, typename T>
void test1(T* obj) {
obj->*member = 10.;
}
auto main() -> int {
auto o = obj();
test1<&obj::x>(&o);
return 0;
}
But the test<&obj::x>(&o) construct has one problem that I cant create my API in a consistent way, because there are situations in which I would like to allow to pass runtime dependent arguments to the test function, instead of the using &obj::x as a template argument. So the other way to solve that is:
struct obj {
double x;
};
template <typename T, typename MemberType>
void test2(T* obj, MemberType T::*const& member) {
obj->*member = 10.;
}
auto main() -> int {
auto o = obj();
test2(&o, &obj::x);
return 0;
}
But now &obj::x is a runtime dependent value. Is there a way that allows me to call test1 from test2 in case that the argument passed to test2 is already known at compile-time?
I know that this is possible with constexpr variables:
struct obj {
double x;
};
template <auto member, typename T>
void test1(T* obj) {
obj->*member = 10.;
}
auto main() -> int {
auto o = obj();
constexpr double obj::*member = &obj::x;
test1<member>(&o);
return 0;
}
But is there a way to do this for a function parameter?
I can't make any assumptions about the object passed to the function nor about the type of the member variable.
Background information:
I want to create a general-purpose timeline function, that allows to interpolate the values of member variables. And to invoke callback function at certain keyframes.
timeline t;
t.add_keyframe<&obj::x>(0, &o, 10. /* easing function */);
t.add_keyframe<&obj::x>(10, &o, 20. /* easing function */);
t.add_keyframe(10, [](time_t t) {
// do something
});
It is not a big deal that I have t.add_keyframe<&obj::x>(…) and t.add_keyframe(, I was just wondering if t.add_keyframe(10, &o, &obj::x, … ); is somehow possible but with compile-time resolving of the member pointer.