I want to know the difference between Lambda and Named function in C++.
Let's first learn few terms 'free function', 'forward declaration', and 'named function'.
Free Function
struct X {
void f() {} // not a free function
};
void g() {} // free function
int h(int, int) { return 1; } // also a free function
Invoking a member function from a member function
// friend functions#include <iostream>using namespace std;
class Rectangle {protected: int width, height; int find_area(int x, int y) const { return x*y; }};
class Square : public Rectangle{public:int duplicate (const int& l, const int& r){ int res = find_area(l, r); //int res = this->find_area(l, r); return res;}};
int main () { Square sq; cout << sq.duplicate (2, 3) << endl;
return 0;}
Click here to work on the above program.
The implicit *this will invoke a member function as Square inherited Rectangle. The below both
are same.
int res = find_area(l, r);
int res = this->find_area(l, r);
If duplicate is not a member function, there will not be an implicit *this.
Invoking a member function from a freestanding(non-member)
To call a member function from freestanding function, befriending the free function won't be suffice.
// friend functions#include <iostream>using namespace std;
class Rectangle {protected: int width, height; int find_area(int x, int y) const { return x*y; }public: friend int duplicate (const int&, const int&);};
int duplicate (const int& l, const int& r){ int res = find_area(l, r); return res;}
int main () { cout << duplicate (2, 3) << endl;
return 0;}
Output
<source>: In function 'int duplicate(const int&, const int&)':<source>:18:13: error: 'find_area' was not declared in this scope18 | int res = find_area(l, r);| ^~~~~~~~~
Click here for the above program
The above program requires an instance of the class.
There are two ways to achieve this:
1. Pass a reference to duplicate
2.
Pass a class reference to a free function
// friend functions#include <iostream>using namespace std;
class Rectangle { int width, height; int find_area(int x, int y) const { return x*y; }public: Rectangle() {} friend int duplicate (const int&, const int&, const Rectangle&);};
int duplicate (const int& l, const int& r, const Rectangle& param){ int res = param.find_area(l, r); return res;}
int main () { Rectangle rec; cout << duplicate (2, 3, rec) << endl;
return 0;}
Output
6
Click here for the above program.
Forward Declaration
Forward declaration refers to the beforehand declaration of the syntax or signature of an identifier, variable, function, class, etc. prior to its usage (done later in the program)
If a class B is defined after class A, but class A's member function uses the class B, it might throw error if Class A's object is first initialised.
Named Function
Named function is a function which has name unlike Lambda.
Eg: member function & free functions.
What is Lambda?
- Lambdas are user-defined nameless functions, but it is not a user-define function.
- Lambda is not a function. It is neither a free function nor a named function.
- A lambda is an object of a closure type with an overloaded call operator.
- Lambda can't have forward declaration.
Practically you define something akin to
[captures]( parameters ){ body; }
class __lambda_SOME_ID
{
captures ...;
auto operator( parameters ... )
{
body;
}
};
The major difference is that they "capture" some variables from the scope that they're defined within.
Lambda has no declaration
Since Lambda doesn't have names, they can't be declared. Because, you can't name its type beforehand.
They just get defined. Lambda is defined and used it to initialize a reference to that function. The reference is called print.
Lambdas are mostly used for small things that you only need locally within another function. I.e. as a predicate to a standard algorithm.
We don't want to care about the functionality of the below code because we are interested only to know the difference between lambda and name function.
#include <iostream>
#include <vector>
using namespace std;
vector<int> convert(int x) {
vector<int> ret;
do {
ret.push_back(x & 1);
}while(x>>=1);
reverse(ret.begin(),ret.end());
return ret;
}
auto print = [] (auto const& v) {
for(const auto& e : v) { cout << e << " "; }
cout << endl;
};
int printStd(vector<int> v) {
for (auto i = v.begin(); i != v.end(); i++) {
cout << *i << " ";
}
return 0;
}
int main()
{
int x = 98;
vector<int> y = convert(x);
print(y); // Method 1 - Lambda
printStd(y); // Method 2 - user defined function
return 0;
}
Print lambda can print any iterable whereas named function printStd does accept only vector of integers. print is the identifier of a Lambda. Lambda uses auto template feature so it does accept any data type. Let's make both function accept any data type. So, let's change it first.
#include <iostream> #include <vector> using namespace std; vector<int> convert(int x) { vector<int> ret; do { ret.push_back(x & 1); }while(x>>=1); reverse(ret.begin(),ret.end()); return ret; } auto print = [] (auto const& v) { for(const auto& e : v) { cout << e << " "; } cout << endl; }; template <typename T> int printStd(auto v) { for (auto i = v.begin(); i != v.end(); i++) { cout << *i << " "; } cout << endl; return 0; } int main() { int x = 98; vector<int> y = convert(x); print(y); // Method 1 - Lambda printStd(y); // Method 2 - user defined function return 0; }
Warning
|
Line 14: error: ISO C++ forbids declaration of 'print' with no type
compilation terminated due to -Wfatal-errors. |
auto is not used for regular function, so you can use template.
Click here to debug the code.
#include <iostream> #include <vector> using namespace std; vector<int> convert(int x) { vector<int> ret; do { ret.push_back(x & 1); }while(x>>=1); reverse(ret.begin(),ret.end()); return ret; } auto print = [] (auto const& v) { for(const auto& e : v) { cout << e << " "; } cout << endl; }; template <typename T> int printStd(T& v) { for (auto i = v.begin(); i != v.end(); i++) { cout << *i << " "; } cout << endl; return 0; } int main() { int x = 98; vector<int> y = convert(x); print(y); // Method 1 - Lambda printStd(y); // Method 2 - user defined function return 0; }
|
Comments
Post a Comment