Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to save pointer to member in compile time?

Consider the following code

template<typename T, int N>
struct A {
  typedef T value_type; // OK. save T to value_type
  static const int size = N; // OK. save N to size
};

Look, it is possible to save any template parameter if this parameter is a typename or an integer value. The thing is that pointer to member is an offset, i.e. integer. Now I want to save any pointer to member in compile time:

struct Foo {
   int m; 
   int r;
};

template<int Foo::*ptr_to_member>
struct B {
   // Next statement DOES NOT WORK!
   static int Foo::* const saved_ptr_to_member = ptr_to_member; 
};

// Example of using
int main() {
    typedef B<&Foo::m> Bm;
    typedef B<&Foo::r> Br;
    Foo foo;
    std::cout << (foo.*(Bm::saved_ptr_to_member));
}

How to save pointer to member in compile time? I use VS2008.

Note. Compile time is critical. Please don't write run-time solution. I know it.

like image 766
Alexey Malistov Avatar asked Dec 16 '09 09:12

Alexey Malistov


People also ask

How do I create a pointer to a member in C++?

The pointer to member operators . * and ->* are used to bind a pointer to a member of a specific class object. Because the precedence of () (function call operator) is higher than . * and ->* , you must use parentheses to call the function pointed to by ptf .

Which is the pointer to a member of a class operator?

There are two pointer to member operators: . * and ->* . The . * operator is used to dereference pointers to class members.

What is pointer to members in C ++? Give their syntax?

It's a "pointer to member" - the following code illustrates its use: #include <iostream> using namespace std; class Car { public: int speed; }; int main() { int Car::*pSpeed = &Car::speed; Car c1; c1.speed = 1; // direct access cout << "speed is " << c1.speed << endl; c1.*pSpeed = 2; // access via pointer to member ...

Can we call member function using this pointer?

Using a pointer-to-member-function to call a function Calling the member function on an object using a pointer-to-member-function result = (object. *pointer_name)(arguments); or calling with a pointer to the object result = (object_ptr->*pointer_name)(arguments);


1 Answers

It would be nice to have more elaborate explanation of why 'compile-time is important' (helps suggesting alternatives). But to my notion everything you need to be done compile time with pointer-to-member, you actually can do. My variant is Thomas's suggestion blended with some C++ philosophy of sort. First lets define:

template <typename T, T v>
struct val
{};

this struct template can effectively serve as compile time value, and you don't need "static value = v;", to use it either at compile or run time. Consider:

template <int n>
struct Foo
{
  //something dependent on n
};

and

template <typename T>
struct Bar;

template <int n>
struct Bar <val <int, n> >
{
  //something dependent of n
};

Foo and Bar are functionally equivalent, every template meta-kadabra which can be done with Foo can also be done with Bar (just pass val instead of n). The same vay you can pack pointer to member into val<>:

val <typeof (&My::a), &My::a>

these compile time values now can be stored in type lists (like boost::mpl::something), compared, transformed, etc., everything compile time. And when you will finally want to use them as pointer-to-member at run time, 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 ()));

P.S.: there are some clumsy constructs about this solution, but it is all for sake of simplicity and explanation. For example rather ugly (a .* extract (a_i ())) may be simplified by wrapping it into something more pointer-to-member specific:

template <typename M, typename C>
typename mem_type <M>::value &
mem_apply (C &c)
{
   M m;
   return c .* extract (m);
}

where mem_type is class template which extracts type of member referred by M. Then usage would be:

std::cout << mem_apply <a_i> (a);
like image 85
jarero Avatar answered Oct 14 '22 14:10

jarero