Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is a lambda in C++ never DefaultConstructible

Tags:

I'm having lambdas that don't capture anything, like

[](){};

I have a template class, that contains such a lambda. Since the lambda does not contain non-static data members, nor virtual functions, it should be an empty class and DefaultConstructible. It's only a kind of policy class usable for template metaprogramming. I would like to know, why such a class is not default constructible by the C++ standard.

Sidenote: Understanding how Lambda closure type has deleted default constructor is asking a different question, though the title seems to be very similar. It is asking how a stateless lambda-object is created without usable default constructor. I'm asking why there is no usable default constructor.

like image 341
Ralph Tandetzky Avatar asked Aug 02 '16 14:08

Ralph Tandetzky


1 Answers

Lambdas are intended to be created then used. The standard thus says "no, they don't have a default constructor". The only way to make one is via a lambda expression, or copies of same.

They are not intended for their types to be something you keep around and use. Doing so risks ODR violations, and requiring compilers to avoid ODR violations would make symbol mangling overly complex.

However, in C++17 you can write a stateless wrapper around a function pointer:

template<auto fptr>
struct function_pointer_t {
  template<class...Args>
  // or decltype(auto):
  std::result_of_t< std::decay_t<decltype(fptr)>(Args...) >
  operator()(Args&&...args)const
    return fptr(std::forward<Args>(args)...);
  }
};

And as operator void(*)() on [](){} is constexpr in C++17, function_pointer_t<+[](){}> is a do-nothing function object that is DefaultConstructible.

This doesn't actually wrap the lambda, but rather the pointer-to-function that the lambda produces.

like image 91
Yakk - Adam Nevraumont Avatar answered Sep 19 '22 04:09

Yakk - Adam Nevraumont