比较constexpr-if条件中的constexpr函数参数会导致错误

时间:2017-07-28 15:26:36

标签: c++ constexpr c++17 static-assert if-constexpr

我试图比较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工作得很好。

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

谢谢!

2 个答案:

答案 0 :(得分:7)

来自constexpr if

  

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

然后,从constant expression

  

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

显然,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不会使其成为编译时常量。它只是意味着您无法更改函数内的参数。

答案 1 :(得分:1)

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

简而言之,test_int_no_if中的任何内容都不依赖于我是constexpr,而在test_int()中则有。 (“constexpr if”仅适用于编译时表达式。)