Use C++ templates instead of macro-defined variations