francesco
francesco

Reputation: 7549

lambda capture error with gcc, compiles with clang

The following program does not compile with g++ 10.1.0

#include <iostream>

template <unsigned int N>
struct A {
  constexpr static unsigned int i = N;
};

template <class U>
void f()
{
  constexpr unsigned int i = U::i;
  auto lambda = [&]() {
    if constexpr (i > 2) {
      std::cout << "i > 2" << std::endl;
    }
    else {
      std::cout << "i <= 2" << std::endl;
    }
  };
  lambda();
}

int main()
{
  f<A<1>>();
  f<A<3>>();
  
  return 0;
}

With

g++ -Wall -std=c++17 -O3 -pedantic -o test test.cpp

the error is:

test.cpp: In lambda function:
test.cpp:13:24: error: lambda capture of ‘i’ is not a constant expression
   13 |     if constexpr (i > 2) {

However, the same code compiles fine with clang++ 11.1.0 and produces the expected result.

Which compiler is correct?

Upvotes: 4

Views: 472

Answers (1)

2b-t
2b-t

Reputation: 2564

Normally you would not need to capture it at all: A lambda expression can read the value of a variable without capturing it if the variable: has const non-volatile integral or enumeration type and has been initialized with a constant expression, or is constexpr and has no mutable members.

This also works in GCC:

auto lambda = []() {
    if constexpr (i > 2) {
      std::cout << "i > 2" << std::endl;
    }
    else {
      std::cout << "i <= 2" << std::endl;
    }
};

Try it here.

Upvotes: 1

Related Questions