Я хочу сравнить метапрограммирование и использование constexpr в c ++ 0x.
тогда я пишу FIB-функцию в обеих моделях.
когда я использую модель метапрограммирования, ответ распечатывается очень быстро, потому что он рассчитывается во время компиляции. но когда я использую функцию constexpr, она вычисляет значение во время выполнения, а не во время компиляции.
Я использую g ++ (gcc) 4.8. Может ли какое-нибудь тело помочь мне?
#include <iostream>
using namespace std;
#define NUM 42
template <unsigned int N>
struct Fibonacci {
enum { value = Fibonacci<N - 1>::value + Fibonacci<N - 2>::value };
};
template <>
struct Fibonacci<1> {
enum { value = 1 };
};
template <>
struct Fibonacci<0> {
enum { value = 1 };
};
constexpr unsigned int fib(unsigned int n)
{
return (n > 1 ? fib(n-1) + fib(n-2) : 1 );
}
int main()
{
cout << "Meta_fib(NUM) : " << Fibonacci<NUM>::value << endl; // compile time :)
cout << "Constexpr_fib(NUM) : " << fib(NUM) << endl; // run time :-?
return 0;
}
Я считаю, что причина в том, что constexpr
не гарантируется выполнение во время компиляции. Чтобы обеспечить оценку во время компиляции, вы должны назначить ее псевдониму во время компиляции. Подобно,
enum {i = fib(NUM)};
По крайней мере, с помощью gcc вы можете получить значение constexpr, которое будет вычислено во время компиляции, сделав его статической переменной:
static const unsigned fibNUM = fib(NUM);
Когда я читаю стандарт, все еще разрешено вычислять значение при запуске, но на практике оно будет вычислено во время компиляции.
Простой тест, чтобы увидеть, если ваш constexpr
на самом деле делается во время компиляции, чтобы использовать std::array
:
#include <array>
std::array<int, Fibonacci<5>::value> arr;
std::array<int, fib(5)> arr2;
Видеть это комментарий Бьярна Страуструпа:
… в соответствии со стандартом функция constexpr может быть оценена в
время компиляции или время выполнения, если оно не используется в качестве константного выражения,
в этом случае это должно быть оценено во время компиляции. Гарантировать
оценка во время компиляции, мы должны либо использовать ее там, где постоянная
требуется выражение (например, в виде границы массива или в качестве метки регистра) или
используйте его для инициализации constexpr. Буду надеяться что нет уважающего себя
Компилятор упустит возможность оптимизации, чтобы сделать то, что я
Первоначально сказано: «Функция constexpr оценивается во время компиляции, если
все его аргументы являются константными выражениями. «
constexpr
не гарантируется, что будет оцениваться во время компиляции. Это означает, что компилятор может выбирать, выполнять ли оценку во время компиляции или во время выполнения.
Вы можете попытаться присвоить его постоянной времени компиляции и проверить, как это …
const long i = fib(NUM);// here i should be initialized at the time of
// declaration
cout << "Meta_fib(NUM) : " << Fibonacci<NUM>::value << endl;
cout << "Constexpr_fib(NUM) : " << i << endl;