简体   繁体   English

constexpr函数在编译时不计算值

[英]constexpr function not calculate value in compile time

I want to compare meta programming and use of constexpr in c++0x. 我想比较元编程和c ++ 0x中constexpr的使用。 then I write a fib function in both model. 然后我在两个模型中写了一个fib函数。 when I use meta programming model, answer print out very fast because it calculated in compile time. 当我使用元编程模型时,答案打印速度非常快,因为它是在编译时计算的。 but when I use constexpr funcion it calculate value in run time, not in compile time. 但是当我使用constexpr函数时,它会在运行时计算值,而不是在编译时。 I using g++( gcc ) 4.8 .can any body help me? 我使用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;
}

I believe the reason is that constexpr is not guaranteed to execute at compile-time. 我相信原因是constexpr不能保证在编译时执行。 To enforce compile-time evaluation, you have to assign it to a compile-time alias. 要强制执行编译时评估,必须将其分配给编译时别名。 Like, 喜欢,

enum {i = fib(NUM)};

With gcc, at least, you can get the constexpr value to be computed at compile time by making it a static variable: 至少使用gcc,你可以通过使它成为静态变量来获得在编译时计算的constexpr值:

static const unsigned fibNUM = fib(NUM);

As I read the standard, it's still allowed to compute the value at startup, but in practice it will be computed at compile time. 当我阅读标准时,它仍然允许在启动时计算值,但实际上它将在编译时计算。

A simple test to see if your constexpr are really being done at compile-time is to use an std::array : 一个简单的测试,看看你的constexpr是否真的在编译时完成是使用std::array

#include <array>

std::array<int, Fibonacci<5>::value> arr;
std::array<int, fib(5)> arr2;

gcc has no complaints . gcc没有抱怨

See this comment by Bjarne Stroustrup : 请参阅Bjarne Stroustrup的评论

... according to the standard a constexpr function may be evaluated at compiler time or run time unless it is used as a constant expression, in which case it must be evaluated at compile-time. ...根据标准,constexpr函数可以在编译器时或运行时计算,除非它被用作常量表达式,在这种情况下,它必须在编译时进行评估。 To guarantee compile-time evaluation, we must either use it where a constant expression is required (eg, as an array bound or as a case label) or use it to initialize a constexpr. 为了保证编译时评估,我们必须在需要常量表达式的地方使用它(例如,作为数组绑定或作为case标签)或使用它来初始化constexpr。 I would hope that no self-respecting compiler would miss the optimization opportunity to do what I originally said: "A constexpr function is evaluated at compile time if all its arguments are constant expressions." 我希望没有自尊的编译器会错过我最初所说的优化机会:“如果constexpr函数的所有参数都是常量表达式,那么它将在编译时进行评估。”

constexpr is not guaranteed to be evaluated at compile time. constexpr不保证在编译时进行评估。 This means, compiler can choose whether to evaluate at compile time or at run time. 这意味着,编译器可以选择是在编译时还是在运行时进行求值。 You can try to assign it to a compile time constant and check like this... 您可以尝试将其分配给编译时常量并像这样检查...

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM