Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ constexpr函数在编译时不计算值_C++_C++11_Template Meta Programming_Compile Time_Gcc4.8 - Fatal编程技术网

C++ constexpr函数在编译时不计算值

C++ constexpr函数在编译时不计算值,c++,c++11,template-meta-programming,compile-time,gcc4.8,C++,C++11,Template Meta Programming,Compile Time,Gcc4.8,我想比较元编程和c++0x中constexpr的使用。 然后我在这两个模型中都写了一个fib函数。 当我使用元编程模型时,答案打印得非常快,因为它是在编译时计算的。但当我使用constexpr函数时,它在运行时计算值,而不是在编译时。 我正在使用g++(gcc)4.8。有人能帮我吗 #include <iostream> using namespace std; #define NUM 42 template <unsigned int N> struct Fibona

我想比较元编程和c++0x中constexpr的使用。 然后我在这两个模型中都写了一个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;
}
#包括
使用名称空间std;
#定义数字42
模板
结构斐波那契{
枚举{value=Fibonacci::value+Fibonacci::value};
};
模板
结构斐波那契{
枚举{值=1};
};
模板
结构斐波那契{
枚举{值=1};
};
constexpr无符号整数fib(无符号整数n)
{
返回(n>1?fib(n-1)+fib(n-2):1);
}
int main()
{

cout我认为原因是
constexpr
不能保证在编译时执行。要强制执行编译时求值,必须将其分配给编译时别名。例如


enum{i=fib(NUM)};

一个简单的测试,看看您的
constepr
是否真的在编译时完成,就是使用
std::array

#include <array>

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

见此:

…根据标准,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;
const long i=fib(NUM);//这里我应该在
//声明

cout使用gcc,您至少可以通过将constexpr值设置为静态变量,从而在编译时获得要计算的constexpr值:

static const unsigned fibNUM = fib(NUM);

在我阅读该标准时,它仍然允许在启动时计算值,但实际上它将在编译时计算。

你怎么知道它在运行时计算值?你看过程序集了吗?@juanchopanza:gcc编译,它在运行时计算。尽管你可以简单地用
cons强制编译时计算texpr无符号i=fib(NUM)
@juanchopanza:您只需运行它。您可以看到循环在打印输出之前旋转。@juanchopanza:这是一种简单的方法;)当我运行此代码时,元编程模型的响应速度很快,但constexpr模型的响应速度非常慢。然而,这不会导致编译器抱怨。只需使用constexpr作为模板参数即可强制编译器在编译时对其求值。当然,如果函数满足
constexpr
的严格要求,这是可能的(否则编译器会更早地抱怨)。但是,它可能在运行时在不同的位置对同一函数求值(值得注意的是,gcc就是这样做的!您可能会认为,一旦compiletime出现,编译器就足够聪明,可以记住这一点,用于所有用途。事实并非如此。)有什么方法可以使它被强制计算,甚至不分配给常量变量?我不确定我是否正确理解了这个问题。除了在“常量上下文”中使用它之外,您是否在寻求另一种方法来保证编译时计算?这个问题的答案可能是“否”。例如,我想传递
constepr函数的结果
(A)作为另一个
正常功能的参数
(B)但是我没有办法使结果保持常量。一个解决方案是使用一个中间的
常量变量来保存结果,然后将
常量变量传递给函数B,这是我不想要的。如果必须绝对保证编译时计算,我想没有更好的方法来实现这一点。这很酷,但是为什么不添加4个字符const->constexpr并保证所有内容?@RiaD:你有标准的报价来证明这一保证吗?