4
votes

I have the following template metaprogramming implementation of factorial:

#include <iostream>

template <int n> struct factorial{
  static const int res = n*factorial<n-1>::res;
};

template <> struct factorial<0>{
  static const int res = 1;
};

int main(){
  std::cout << factorial<5>::res << '\n';
  return 0;
}

This code compiles successfully and outputs 120, as expected. However, for purely self-enjoying reasons, I would like to instead make it not compile, and instead display 120 in the error message of the compiler.

Is there a simple syntax mistake I can deliberately enter into my code to get it to fail to compile and yet still print the value of 5!, i.e. 120, in the compiler error message?

I anticipate that the answer will probably be compiler dependent; I am currently using g++ that came with Xcode Mac OSX, which iirc is a frontend for clang.

2
If you allow -Werror, this does it. coliru.stacked-crooked.com/a/34dfcdcb110e9bc4 static_assert may be of help to if that's not cheating. - Baum mit Augen
@BaummitAugen: ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ - Lightness Races in Orbit
@LightnessRacesinOrbit Well I guess after this comment I can't quite get away with "might not be useful for OP". :) - Baum mit Augen

2 Answers

8
votes

You could use a declared, but undefined template to print out the value as a compile time error.

template<int n>
class display;

template<int n> struct factorial{
    static const int res = n*factorial<n-1>::res;
};

template<> struct factorial<0>{
    static const int res = 1;
};

int main()
{
    display<factorial<5>::res> value;
}

g++ outputs:

g++ -std=c++11 fact.cxx
fact.cxx: In function ‘int main()’:
fact.cxx:14:29: error: aggregate ‘display<120> value’ has incomplete type and cannot be defined
  display<factorial<5>::res> value;
                             ^
4
votes

If the option -Werror is allowed or if warnings count as errors, this:

#include <iostream>

template <int n> struct factorial{
  static const int res = n*factorial<n-1>::res;
};

template <> struct factorial<0>{
  static const int res = 1;
};

int main(){
  char x[factorial<5>::res];
  return x[sizeof(x)];
}

will produce the error/warning

error: 'x[120ul]' is used uninitialized in this function [-Werror=uninitialized]

using gcc 5.3 or

error: array index 120 is past the end of the array (which contains 120 elements) [-Werror,-Warray-bounds]

using clang 3.8.