我正在学习constexpr
并且,根据我的理解,constexpr
告诉编译器在编译期间计算函数而不是运行时间。我使用以下代码进行测试,但遇到了一个我真不理解的错误。你能解释一下原因吗?
#include <iostream>
#include <array>
using namespace std;
constexpr int foo(int i)
{
return i + 5;
}
int main()
{
int i = 10;
std::array<int, foo(5)> arr; // OK
// But...
std::array<int, foo(i)> arr1; // Error
}
错误是:&#39; i
&#39;不能用于常量表达式。为什么?事先声明i
为什么它必须是const
?
答案 0 :(得分:5)
对于我的理解,constexpr告诉编译器在编译期间计算函数而不是运行时间。
不完全是:使用constexpr
编译器可以(不必)计算函数编译时间。编译器会在必要和可能的情况下执行此操作。
如果是
std::array<int, foo(5)> arr; // OK
它是必要的(因为std::array
的第二个模板参数必须在编译时知道)并且可能(因为5在编译时是已知的)。
但是
int i = 10;
std::array<int, foo(i)> arr1; // Error
它是必要的(std::array
)但不可能(因为i
是一个非常量变量,编译器无法使用i
值编译时间但只是运行时间。)
这是必要但不可能,所以错误。
但你可以写
int i { 10 };
int j { foo(i) };
因为它不可能调用foo(i)
编译时间但是没有必要(因为j
可以在运行时初始化)。所以foo(i)
被称为(假设)运行时间。
要使用std::array
汇编foo(i)
,您应将i
定义为constexpr
(或const
)
constexpr int i { 10 };
因此编译器可以使用i
编译时的值。
为什么呢?我事先声明为什么它必须是一个const?
简短回答:因为C ++ 11标准这么说。
答案很长:因为,通过这种方式,构建编译器变得更简单。如果要使用值编译时,可以将其声明为constexpr
,编译器会检查它是否永远不会被修改。它(相对)很简单。
否则,如果您可以使用编译时非常量变量的值,编译器应该遵循变量的故事来确定它在constexpr
函数中使用时的值。在你的玩具例子很简单,在现实生活中将是一场噩梦。