Debugging template instantiations

Solution 1:

These are pretty basic, but they have worked for me in most cases. I'm interested to see what others have to say too.

Apologies for the contrived examples.

Use sandboxes

Starting with small sandboxes to test template code as soon as it starts behaving weird or you are doing something complicated. I am pretty comfortable with templates and I still do this almost immediately. Simply, it uncovers errors faster. You have done it for us here, so I presume that this is moot.

Specify temporary types

Temporaries can obfuscate where your intentions are not met. I have seen a lot of code that does something like the below.

template<typename T>
  T calc(const T &val) {
    return some_other_calc(val) / 100.0;
  }

Telling the compiler what type you expect will fail faster and potentially will give you a better message to deal with.

template<typename T>
  T calc(const T &val) {
    T val_ = some_other_calc(val);
    return val_ / 100.0;
  }

Use typeid

Using typeid(T).name() to print template names in debug statements. This will give you a string that you can use to see how the compiler decided to fulfill the type.

template<typename T>
  typename void test() {
    std::cout << "testing type " << typeid(T).name() << std::endl;
    // ...
  }

Avoid unnecessary default implementations

Write templates in such a way that they don't have default implementations.

template<typename T, bool is_integral = boost::is_numeric<T>::value >
  struct my_traits;

template<typename T>
  struct my_traits<T, true> {
    typedef uint32_t cast_type;
  };

template<typename T>
  void print_whole_number(T &val) {
    std::cout << static_cast<my_traits<T>::cast_type>(val) << std::endl;
  }

This enforces users of print_whole_number have their own my_traits specialization. They will get an compiler error instead of half working because you couldn't supply a good implementation for all types. The compiler error won't be immediately helpful if used in a disparate part of a code base, admittedly.

Solution 2:

Yes, there is a template metaprogramming debugger. Templight