1

我正在尝试比较 constexpr-if 语句中的函数参数。

这是一个简单的例子:

constexpr bool test_int(const int i) {
  if constexpr(i == 5) { return true; }
 else { return false; }
}

但是,当我使用带有以下标志的 GCC 7 编译它时: g++-7 -std=c++1z test.cpp -o test 我收到以下错误消息:

test.cpp: In function 'constexpr bool test_int(int)':
test.cpp:3:21: error: 'i' is not a constant expression
 if constexpr(i == 5) { return true; }

但是,如果我test_int用不同的功能替换:

constexpr bool test_int_no_if(const int i) { return (i == 5); }

然后下面的代码编译没有错误:

int main() {
  constexpr int i = 5;
  static_assert(test_int_no_if(i));
  return 0;
}

我不明白为什么 constexpr-if 版本无法编译,特别是因为 static_assert 工作得很好。

对此的任何建议将不胜感激。

谢谢!

4

2 回答 2

7

constexpr 如果

在 constexpr if 语句中,条件的值必须是上下文转换的 bool 类型的常量表达式

然后,从常量表达式

定义一个可以在编译时计算的表达式。

显然,i == 5它不是一个常量表达式,因为i它是一个在运行时计算的函数参数。这就是编译器抱怨的原因。

使用函数时:

constexpr bool test_int_no_if(const int i) { return (i == 5); }

那么它可能会在编译时进行评估,具体取决于它的参数在编译时是否已知。

如果i定义如下:

constexpr int i = 5;

那么 的值i在编译期间是已知的,并且test_int_no_if可能在编译期间被评估,从而可以在内部调用它static_assert

另请注意,将函数参数标记为const不会使其成为编译时间常数。这只是意味着您不能更改函数内部的参数。

于 2017-07-28T15:48:48.470 回答
2

可以使用非 constexpr 参数调用 constexpr 函数,在这种情况下,它的行为与普通函数一样,因此代码仍必须像不是 constexpr 一样编译。

简而言之,test_int_no_if 中没有任何东西取决于 i 是 constexpr,而在 test_int() 中,有。(“constexpr if”仅适用于编译时表达式。)

于 2017-07-28T15:58:46.247 回答