c – `if constexpr`,内部lambda,内部包扩展 – 编译器错误?

前端之家收集整理的这篇文章主要介绍了c – `if constexpr`,内部lambda,内部包扩展 – 编译器错误?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
  1. clang version 5.0.0 (trunk 305664)
  2. Target: x86_64-unknown-linux-gnu

以下代码成功编译:

  1. template <int... A>
  2. void f() {
  3. ([](auto) {
  4. if constexpr (A == 0)
  5. return 42;
  6. else
  7. return 3.14;
  8. }(0),...);
  9. }
  10.  
  11. int main() {
  12. f<0,1>();
  13. }

……但是这个没有:

  1. template <int... A>
  2. void f() {
  3. ([](auto...) { // Variadic lambda
  4. if constexpr (A == 0)
  5. return 42;
  6. else
  7. return 3.14;
  8. }(),...); // No argument
  9. }
  10.  
  11. int main() {
  12. f<0,1>();
  13. }

…屈服:

  1. <source>:7:13: error: 'auto' in return type deduced as 'double' here but deduced as 'int' in earlier return statement
  2. return 3.14;
  3. ^
  4. <source>:3:6: note: in instantiation of function template specialization 'f()::(anonymous class)::operator()<>' requested here
  5. ([](auto...) { // Variadic lambda
  6. ^
  7. <source>:12:5: note: in instantiation of function template specialization 'f<0,1>' requested here
  8. f<0,1>();
  9. ^

我不希望在空参数包和伪参数之间有不同的行为.

是否存在这种差异的原因,或者这是编译器错误

解决方法

我相信这是一个铿锵的错误.

[dcl.spec.auto]中的规则强调我的:

If the declared return type of the function contains a placeholder type,the return type of the function is deduced from non-discarded return statements,if any,in the body of the function ([stmt.if]).

[…]

If a function with a declared return type that contains a placeholder type has multiple non-discarded return statements,the return type is deduced for each such return statement. If the type deduced is not the same in each deduction,the program is ill-formed.

lambda中的一个或另一个return语句被丢弃(如果constexpr被称为废弃语句,则取非分支),只留下一个非废弃的return语句,因此lambda的返回类型应该简单地从中推断出来.一个遗留下来.

此外,clang还可以这样:

  1. template <int A>
  2. void f() {
  3. [](auto...) {
  4. if constexpr (A == 0)
  5. return 42;
  6. else
  7. return 3.14;
  8. }();
  9. }
  10.  
  11. int main() {
  12. f<0>();
  13. f<1>();
  14. }

所以这可能与lambdas在pack表达式中的工作方式有一些不良的交互.

猜你在找的C&C++相关文章