Generic programming, as used by the std and boost packages, depends heavily on template tricks to extract data from specific data structures in a generic way. When I first tried using some of the boost libraries, I felt pretty clueless in getting them to do what I wanted. Hence this post.
Say you have a C struct like this one:
struct Foo { int a; int b; };
Generic programming accesses the a and b members using a global get function and a property map:
template <typename T, typename PMAP> int get(T &t, PMAP pmap);
What’s in the property map? In this case nothing. The magic happens in the templated specialization of get:
struct get_a {}; int get(Foo &foo, get_a) { return foo.a; }
Which you call like this:
Foo f1; f1.a = 10; std::cout << "a is " << get(f1, get_a()) << std::endl;
How’s it work and what’s the compiled result?
The get_a struct is empty; it contains no data members. When you call get, the compiler selects the get_a version since it’s the most specific specialization of get. From there, things get interesting. Constructing get_a() is a noop. Pushing it as a function argument is a noop. After inlining, get simply becomes f1.a.