I have the following code that compiles and works correctly due to such a concept as Input/output manipulators:
#include <iostream>
#include <ostream>
struct st{
auto mke(){
return [](std::ostream& os) -> decltype(auto) {return os<<42;};
}
};
int main(){
std::cout<<st{}.mke();
}
But actually, in my project, I need to capture this by reference and output some fields of the structure. Something like this:
#include <iostream>
#include <ostream>
struct st{
int a=42;
auto mke(){
return [this](std::ostream& os) -> decltype(auto) {return os<<a;};
}
};
int main(){
std::cout<<st{}.mke();
}
But it doesn’t compile.
Q: I need a detailed explanation of the reasons preventing the compilation of the second example. What really happened?
>Solution :
In the first example, overload resolution looks at all the various operator<< that are defined in the global namespaces and in std, and finds basic_ostream& operator<<(std::basic_ostream<CharT, Traits>& (*func)(std::basic_ostream<CharT, Traits>&) );. This is a viable overload because there exists a conversion from non-capturing-lambda closure-object to pointer-to-function (of a matching signature).
In the second example, the function pointer overload of operator<< isn’t viable, because the closure object of a capturing lambda doesn’t have a pointer-to-function conversion.