It would be nice to have a more detailed explanation of why compilation time is important (helps suggest alternatives). But, in my opinion, all you need to do, compile time with a member pointer, you really can do. My option is Thomas' suggestion mixed with some C ++ philosophy. First, let's define:
template <typename T, T v> struct val {};
this structure template can effectively serve as a compile-time value, and you do not need βstatic value = v;β to use it either at compile time or at run time. Consider:
template <int n> struct Foo {
and
template <typename T> struct Bar; template <int n> struct Bar <val <int, n> > {
Foo and Bar are functionally equivalent, each metadabra template that can be done with Foo can also be done with Bar (just skip val instead of n). In the same vay you can pack a pointer to a member in val <>:
val <typeof (&My::a), &My::a>
these compilation time values ββcan now be stored in type lists (for example, boost :: mpl :: something), compared, converted, etc., all the time compilation. And when you finally want to use them as a pointer to an element at runtime, just define one function template:
template <typename T, T value> T extract (val <T, value>) { return value; }
and use it:
typedef val <typeof (A::i), A::i> a_i; A a; std::cout << (a .* extract (a_i ()));
PS: There are some clumsy constructions about this solution, but all for the sake of simplicity and explanation. For example, pretty ugly (a. * Extract (a_i ())) can be simplified by moving it to something more specific to a member pointer:
template <typename M, typename C> typename mem_type <M>::value & mem_apply (C &c) { M m; return c .* extract (m); }
where mem_type is the class template that retrieves the type of the member referenced by M. Then use will be:
std::cout << mem_apply <a_i> (a);