Using a phony C struct as a function selector


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:
[code]
struct Foo {
int a;
int b;
};
[/code]
Generic programming accesses the a and b members using a global get function and a property map:
[code]
template <typename T, typename PMAP>
int get(T &t, PMAP pmap);
[/code]
What’s in the property map? In this case nothing. The magic happens in the templated specialization of get:
[code]
struct get_a {};
int get(Foo &foo, get_a)
{
return foo.a;
}
[/code]
Which you call like this:
[code]
Foo f1;
f1.a = 10;
std::cout << "a is " << get(f1, get_a()) << std::endl;
[/code]

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.
 


Leave a Reply

Your email address will not be published. Required fields are marked *