ors*_*onl 0 c++ metaprogramming constexpr c++11 stdarray
我正在学习,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
}
Run Code Online (Sandbox Code Playgroud)
错误是:' i' 的值在常量表达式中不可用.为什么?i事先声明为什么它必须是一个const?
为了我的理解,constexpr告诉编译器在编译期间计算函数而不是运行时间.
不完全是:用constexpr编译器可以(不必)计算函数编译时间.编译器会在必要和可能的情况下执行此操作.
的情况下
std::array<int, foo(5)> arr; // OK
Run Code Online (Sandbox Code Playgroud)
这是必要的(因为第二个模板参数std::array必须在编译时知道)并且可能(因为5在编译时是已知的).
但随着
int i = 10;
std::array<int, foo(i)> arr1; // Error
Run Code Online (Sandbox Code Playgroud)
它是必要的(std::array)但不可能(因为它i是一个非常量变量,编译器不能使用i值编译时但只能运行时).
这是必要的,但不可能,所以错误.
但你可以写
int i { 10 };
int j { foo(i) };
Run Code Online (Sandbox Code Playgroud)
因为调用foo(i)编译时间不可能,但是没有必要(因为j可以初始化运行时).因此foo(i)被称为(据称)运行时间.
要编译std::array使用foo(i),您应该定义i为constexpr(或const)
constexpr int i { 10 };
Run Code Online (Sandbox Code Playgroud)
所以编译器可以使用i编译时的值.
为什么?我事先被宣布为什么它必须是一个const?
简短回答:因为C++ 11标准这么说.
答案很长:因为,通过这种方式,构建编译器更简单.如果要使用值编译时,可以将其声明为constexpr,并且编译器会检查它是否永远不会被修改.它(相对)很简单.
否则,如果您可以使用编译时非常量变量的值,编译器应该遵循变量的故事来确定它在constexpr函数中使用时的值.在你的玩具例子很简单,在现实生活中将是一场噩梦.
| 归档时间: |
|
| 查看次数: |
542 次 |
| 最近记录: |