1

I have a bit confusion about lambda expression: In C++ primer 5 ed. it is said that :

Classes generated from a lambda expression have a deleted default constructor, deleted assignment operators, and a default destructor. Whether the class has a defaulted deleted copy/move constructor depends in the usual ways on the types of the captured data members (§ 13.1.6, p. 508, and § 13.6.2, p.537).

Now If I try this code:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <map>
using namespace std;


int main() 
{

  auto isOdd = [](int x)->bool{ return x % 2;};

  vector<int> vi{10, 8, 5, 6, 7, 24};

  copy_if(vi.cbegin(), vi.cend(), ostream_iterator<int>(cout, ", "), isOdd); // why this works even on C++11?


  auto greater = [](auto x, auto y) { return x > y; };
  std::map<std::string, int, decltype(greater)> map; // this doesn't work?

}
  • I don't know how could a lambda with a deleted-default ctor can be defined this way:

    auto pow = [](int x){return x * x;};
    cout << pow(5) << endl; // 25
    
  • Why the above works fine even on C++11 although the lambda there has a deleted default-ctor?

  • How can you translate this lambda into a class for example equivalent to it?

  • But why C++11 complains when passed to map<>?

  • So can anyone explain what happens when a lambda doesn't capture anything what the compilr does? What does it generate?

E_net4
  • 27,810
  • 13
  • 101
  • 139
Maestro
  • 2,512
  • 9
  • 24
  • 1
    I don't like this duplicate. It doesn't even mention that lambda expression is a prvalue, so `auto pow = [](int x){return x * x;};` invokes move constructor, not default constructor. – Yksisarvinen Apr 21 '20 at 23:27
  • 3
    Was writing a lengthy answer before it got closed, oh well... `auto pow = [](...){...}` doesn't default-construct the lambda. `[](){}` syntax creates a temporary lambda object magically, without using any of its constructors, then `pow` is initialized with that temporary. A proper test of default-constructability would be `decltype(isOdd) foo;` (which in fact compiles since C++20). `std::map map;` doesn't work pre-C++20 because it tries to default-construct the lambda. use `... map(isOdd);`. – HolyBlackCat Apr 21 '20 at 23:27
  • @HolyBlackCat: Thank you first! But why t is marked as duplicated although you can give an interesting explanation? -I don't mean you – Maestro Apr 21 '20 at 23:29
  • @Yksisarvinen: Thank you. I wish they remove the flag "marked as duplicate" so you can elaborate a thorough explanation. – Maestro Apr 21 '20 at 23:30

0 Answers0