Wednesday, May 30, 2007

Conditional statements in C++ Template meta-programming

C++ Template meta-programming is a black-frackin-art -- one of which I am totally in awe of -- that consists entirely of exploiting the corner cases of the specifications type deduction rules.

For your edutaining pleasure, the implementation of is_const <T> in GCC:

  /// @brief  helper classes [4.3].   
<typename T, T v>
struct integral_constant {
static const T value = v;
typedef T value_type;
typedef integral_constant type;
typedef integral_constant true_type;
typedef integral_constant false_type;

   /// @brief  type properties [4.5.3].    
struct is_const : public false_type { };

template<typename T>
struct is_const
: public true_type { };

How it works depends entirely on the template (partial) specialization features of C++. When you have:

template <typename T>
void fun (T val, const true_type&) { do_foo(); }

template <typename T>
void fun (T val, const false_type&) { do_bar(); }

int main() {
typename const int a_type;
typename int b_type;
a_type a = 5;
b_type b = 3;

fun (a, is_const<a_type>);
fun (b, is_const<b_type>);

Temporary objects of types is_const<a_type> and is_const<b_type>, respectively, are made. C++ will try to pick the best match for each parameter type from the list of available classes for is_const<T>. In the case of b_type, the only suitable match is the non-specialized definition, for a_type, the specialization is_const<const> is a better match. That way the overloaded function fun is sent, in the case of a an is_const type that derives from true_type, and in the case of b an is_const type that derives from false_type, and thus is able to dispatch to different routines based on the overload.

No comments: