I am learning C++ using the resource listed here. In particular, i read about lambda expressions in C++ Primer by Lippman. There i came to know that lambdas are function objects. Moreover, classes generated from lambda expressions do not have a default constructor. So take for example:
auto wc = find_if(words.begin(), words.end(),
[sz](const string &a){
return s.size() >= sz;
};
It is written that the above lambda expression will generate a class that will look something like:
class SizeComp {
SizeComp(size_t n): sz(n) { } // parameter for each captured
variable
// call operator with the same return type, parameters, and body as the lambda
bool operator()(const string &s) const
{ return s.size() >= sz; }
private:
size_t sz; // a data member for each variable captured by value
};
So what happens is that an unnamed object of this compiler generated class is created and is passed as the third argument to the std::find_if
shown above. I can understand this.
Now it is my thinking/understanding that since this compiler generated class has no default ctor, so the third argument that is passed to the std::find_if
must not be created using a default ctor since that would fail. So, internally the object that is passed should be created using the parameterized ctor something like:
auto wc = find_if(words.begin(), words.end(), SizeComp(sz)); //note the third argument uses the parameterized ctor
My first question is that since there is no default ctor in case of an empty capture list in C++11, so how will an object of that compiler generated class be created. I mean in case of an empty capture list, there will be no data members inside the compiler generated class so there will be no parameterized ctor. Which means that this compiler generated class has neither default nor parameterized ctor. Then how can an object of this class be generated. For example, the situation shown below won't work when the capture list is empty:
auto wc = find_if(words.begin(), words.end(),
[](const string &a){ //NOTE THE CAPTURE LIST IS EMPTY
return s.size() >= 5;
};
Now, how will the third argument to std::find_if
be created:
auto wc = find_if(words.begin(), words.end(), CompGeneratedClass()); //this can't work because there is no default ctor
I also know that for a normal/ordinary user-defined class if we provide a user-defined ctor, then the compiler will not generate a default ctor for that class. So, it seems to me that since in case of an empty capture list lambda expression there is no user-defined ctor, the compiler should generate a default ctor for this compiler generated class. But the C++ standard says that there won't be a default ctor. So my second question is that why does this compiler generated class has different behavior than an user-defined class.
Also, note that this explanation is not only limited to C++ Primer by Lippman. I've seen the same explanation in CppCon presentations as well.