有条件的功能评估

时间:2014-09-30 16:14:52

标签: c++

好吧,这可能是一个愚蠢的问题,但我完全不理解第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)   计算一些与实现有关的值。

Source for context

我尝试运行上面的代码以尝试更多地理解解释但我收到了错误。有人可以提供更明确的解释吗?

编辑:我创建了一个程序来测试它:

#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));

1 个答案:

答案 0 :(得分:7)

这意味着constexpr函数中的条件分支允许使用非常量表达式(即需要运行时评估的表达式,例如抛出异常),只要在调用函数时从不采用该分支。常量表达式。

可以调用check来初始化constexpr变量val,只要函数的参数是常量表达式,条件{{1}即可是真的。

如果参数不是常量,则函数调用不是常量表达式,因此无法初始化(low<=i && i<high)变量。

如果条件为false,则函数需要采用false分支,这需要抛出异常,这需要运行时评估,因此函数不是常量表达式,因此无法初始化constexpr变量

当参数是常量表达式时,编译器在编译时知道是否将采用分支,因此只要条件为constexpr,它就可以完全忽略true分支,并且并不抱怨在编译时抛出异常是不可能的。

在运行时调用该函数时,它可以有任何参数,并且false分支可以被采用,false将被评估为普通(非constexpr)函数