C
Carlo Milanesi
Consider the following program to convert between units of measurement:
struct MilesPerHour { };
struct KilometersPerHour { };
// Clause 1
template <class FromUnit, class ToUnit>
double ConversionFactor();
// Clause 2
template <>
double ConversionFactor<MilesPerHour, KilometersPerHour>()
{ return 1.609; }
// Clause 3
template <>
double ConversionFactor<KilometersPerHour, MilesPerHour>()
{ return 1 / 1.609; }
#include <iostream>
int main ()
{
std::cout << ConversionFactor<KilometersPerHour, MilesPerHour>()
<< " " << ConversionFactor<MilesPerHour, KilometersPerHour>();
}
It works well, but clause 2 and clause 3 are somewhat redundant.
Therefore I replaced clause 1 with the following:
template <class FromUnit, class ToUnit>
double ConversionFactor()
{ return 1 / ConversionFactor<ToUnit, FromUnit>(); }
Then I could eliminate clause 2 OR clause 3 and the program kept working
well.
But if accidentally I eliminate both clause 2 AND clause 3, every
compiler I tried (gcc, VC++ 2005, VC++ 2008) completed the compilation
with no error messages. When running the (wrong) executable, in two
cases the program terminated silently, and in one case it crashed.
Of course such an executable program had never to be generated.
There is a way to force a compilation error in such a case (of endless
recursion in template instantiation)?
struct MilesPerHour { };
struct KilometersPerHour { };
// Clause 1
template <class FromUnit, class ToUnit>
double ConversionFactor();
// Clause 2
template <>
double ConversionFactor<MilesPerHour, KilometersPerHour>()
{ return 1.609; }
// Clause 3
template <>
double ConversionFactor<KilometersPerHour, MilesPerHour>()
{ return 1 / 1.609; }
#include <iostream>
int main ()
{
std::cout << ConversionFactor<KilometersPerHour, MilesPerHour>()
<< " " << ConversionFactor<MilesPerHour, KilometersPerHour>();
}
It works well, but clause 2 and clause 3 are somewhat redundant.
Therefore I replaced clause 1 with the following:
template <class FromUnit, class ToUnit>
double ConversionFactor()
{ return 1 / ConversionFactor<ToUnit, FromUnit>(); }
Then I could eliminate clause 2 OR clause 3 and the program kept working
well.
But if accidentally I eliminate both clause 2 AND clause 3, every
compiler I tried (gcc, VC++ 2005, VC++ 2008) completed the compilation
with no error messages. When running the (wrong) executable, in two
cases the program terminated silently, and in one case it crashed.
Of course such an executable program had never to be generated.
There is a way to force a compilation error in such a case (of endless
recursion in template instantiation)?