好吧,这可能是一个愚蠢的问题,但我完全不理解第12.1.6.2节 - 在c ++编程语言的constexpr函数下的条件评估。这是非常简短的文本。
条件表达式的一个分支,不在constexpr中 函数未被评估。这意味着没有采取的分支可以 需要运行时评估。例如:
constexpr int check(int i) { return (low<=i && i<high) ? i : throw out_of_range(); } constexpr int low = 0; constexpr int high = 99; // ... constexpr int val = check(f(x,y,z));
您可能会想到低和高是配置参数 在编译时知道,但不是在设计时,f(x,y,z) 计算一些与实现有关的值。
我尝试运行上面的代码以尝试更多地理解解释但我收到了错误。有人可以提供更明确的解释吗?
编辑:我创建了一个程序来测试它:
#include<iostream>
#include<stdexcept>
using namespace std;
constexpr int low = 0;
constexpr int high = 99;
constexpr int check(int i) {
return (low<=i && i<high) ? i : throw out_of_range();
}
constexpr int f(int x, int y, int z) {
return x*y*z;
}
int main() {
constexpr int val = check(f(2,2,2));
cout << val << '\n';
}
它不会运行:
no matching function for call to 'std::out_of_range::out_of_range()' //I'm really surprised at this
return (low<=i && i<high) ? i : throw out_of_range();
error: body of constexpr function 'constexpr int check(int)' not a return-statement
}
error: 'constexpr int check(int)' called in a constant expression
constexpr int val = check(f(2,2,2));
答案 0 :(得分:7)
这意味着constexpr函数中的条件分支允许使用非常量表达式(即需要运行时评估的表达式,例如抛出异常),只要在调用函数时从不采用该分支。常量表达式。
可以调用check
来初始化constexpr
变量val
,只要函数的参数是常量表达式,条件{{1}即可是真的。
如果参数不是常量,则函数调用不是常量表达式,因此无法初始化(low<=i && i<high)
变量。
如果条件为false,则函数需要采用false分支,这需要抛出异常,这需要运行时评估,因此函数不是常量表达式,因此无法初始化constexpr
变量
当参数是常量表达式时,编译器在编译时知道是否将采用分支,因此只要条件为constexpr
,它就可以完全忽略true
分支,并且并不抱怨在编译时抛出异常是不可能的。
在运行时调用该函数时,它可以有任何参数,并且false
分支可以被采用,false
将被评估为普通(非constexpr)函数