Compiletime resolving of member pointer passed as function argument

Viewed 59

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.

0 Answers
Related