Search code examples
c++gccc++17autogeneric-lambda

Incorrect copy constructor while passing argument to generic lambda


Consider this piece of code:

template < auto What >
constexpr auto Identity = [](auto&&...) { return What; };

struct Ban
{
  Ban() = default;
  Ban(const Ban&  ban) = delete;
  Ban(      Ban&& ban) = delete;
};

int main()
{ 
  Ban ban;
  Identity<false>(10,ban);

  return 0;
}

This fails to compile on godbolt.org with gcc-7.3 as it tries to copy the second argument of Identity. Why it should? Is this a bug in gcc?

gcc does not complain if the second argument is a temporary or when there is only one argument. It complains for only one argument when the definition of Identity is with (...) instead of (auto&&...).


Solution

  • The first half is a mis-parse of auto&&... for generic lambdas in older GCC versions: clang vs gcc - empty generic lambda variadic argument pack; Should non-capturing generic lambdas decay to function pointers?; Should non-capturing generic lambdas decay to function pointers?

    The second half is expected. Passing over C-style ... variadics makes a copy and you deleted your copy constructor.