Вычисление и печать факториала во время компиляции на языке C++
template<unsigned int n>
struct Factorial {
enum { value = n * Factorial<n-1>::value};
};
template<>
struct Factorial<0> {
enum {value = 1};
};
int main() {
std::cout << Factorial<5>::value;
std::cout << Factorial<10>::value;
}
Вышеуказанная программа вычисляет факторное значение во время компиляции. Я хочу печатать факториальное значение во время компиляции, а не во время выполнения с помощью cout. Как мы можем добиться печати факториального значения во время компиляции?
Я использую VS2009.
Спасибо!
3 ответа:
Факториал может быть напечатан в сгенерированном компилятором сообщении следующим образом:
template<int x> struct _; int main() { _<Factorial<10>::value> __; return 0; }
Сообщение об ошибке:
Прог.cpp: 14: 32: error: aggregate '_ _ _ ' имеет неполный тип и не может быть определен _::значение> __; ^
Здесь
3628800
является факториалом10
.Смотрите его в ideone: http://ideone.com/094SJz
Так вы ищете это?
Правка:
Матье попросил умного фокус в том, чтобы одновременно напечатать факториал и позволить компиляции продолжаться. Вот одна попытка. Он не выдает никаких ошибок, поэтому компиляция завершается с одним предупреждением.
template<int factorial> struct _{ operator char() { return factorial + 256; } }; //always overflow int main() { char(_<Factorial<5>::value>()); return 0; }
Он компилируется с этим предупреждением:
Главная.cpp: в экземпляре'_:: operator char () [с int факториал = 120]': главное.cpp: 16: 39: требуется отсюда главный.cpp: 13: 48: предупреждение: переполнение при неявном преобразовании констант [- Woverflow] struct _{ оператор char () { возвращаемый факториал + 256; } }; //всегда переполнение
Здесь
120
является факториалом5
.Демо в ideone: http://coliru.stacked-crooked.com/a/c4d703a670060545
Вы можете просто написать хороший макрос и использовать его вместо этого как:
#define PRINT_AS_WARNING(constant) char(_<constant>()) int main() { PRINT_AS_WARNING(Factorial<5>::value); return 0; }
Это выглядит великолепно.
Я изучаю основы TMP и хочу знать результат при компиляции, чтобы убедиться, что логика верна.
В этом случае то, что вы действительно хотите, - это статическое утверждение:
static_assert(Factorial<5> ::value == 120, "5! should be 120"); static_assert(Factorial<10>::value == 3628800, "10! should be 3628800");
Если ваш компилятор еще не поддерживает
static_assert
, Вы можете использоватьBOOST_STATIC_ASSERT
.