Whenever one creates a lambda, the type is always auto, so I was wondering, is the type that it is viewed as always the same type for every kind of lambda or does each lambda have its own unique 'type'? Like could I make a lambda, and then set it equal to a new lambda?
1 2 3 4 5 6 7 8 9 10 11 12
int main(){
auto lambda = [&] (int x,int y) -> int{
int res = x + y;
return res;
}
lambda = [&] (int x,int y) -> int{
int res = x - y;
return res;
}
}
Like could I make a lambda, and then set it equal to a new lambda?
Nope.
cppreference wrote:
The lambda expression is a prvalue expression of unique unnamed non-union non-aggregate class type, known as closure type, which is declared (for the purposes of ADL) in the smallest block scope, class scope, or namespace scope that contains the lambda expression.
Lambda's are basically just syntactic sugar. They don't allow anything that isn't possible without them. They are a convenience.
Their type is unspecified, but in general a lambda creates an object from a class something like Func below. However, it's allowed to create a simple function instead if that is possible.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
#include <iostream>
class Func {
int& x;
public:
Func(int&x) : x(x) {}
voidoperator() (int a, int b) { std::cout << a + b + x << '\n'; }
};
int main() {
int x = 7;
auto f = [&x](int a, int b){std::cout << a + b + x << '\n';};
f(2, 3);
auto g = Func(x);
x = 9;
g(3, 4);
}
Whenever one creates a lambda, the type is always auto
Well, auto isn't a type, per se: it's a placeholder for a real type that the compiler must be able to deduce.
If we try to get the type of a lambda expression by saying decltype([](){}), we'll find that we are forbidden (until C++20) because the expression e in decltype(e) is an unevaluated expression and lambda expressions cannot appear in an unevaluated context;
if we try to say decltype(lambda), we'll find that the type is not very useful, because the type of the closure has a deleted default constructor (until C++20).
auto lambda; is meaningless. What type would lambda be? You need an initializer with auto.
1 2 3 4 5 6 7 8 9 10 11
#include <iostream>
#include <functional>
int main(int argc, char**) {
std::function<void(int,int)> f;
if (argc > 1)
f = [](int a, int b) { std::cout << a + b << '\n'; };
else
f = [](int a, int b) { std::cout << a - b << '\n'; };
f(3, 2);
}
I decided that what I was trying to do was stupid thanks guys!
Well, the question you asked was fine on its own. Still, you might get more useful help if you ask directly about your problem, instead of about a potential solution.
Those mis-directed questions are examples of XY problems: http://xyproblem.info/
@dutch well yes, but does that mean that I can’t just initialize it right after declaration
@mbozzi but that wouldn’t leave any of the fun for me, and besides my ideas are usually ridiculous so I would probably just get a bunch of comments discouraging the idea instead of helping me with it. The solutionproblem was already solved, I was just trying to make it better (believe it or not XD).
Edit: ok I do see your point with the xy thing now though. Still for this one specifically I wouldn’t say it really applied since it was already solved.
auto's point is to avoid having to type out types, either because you want the type of a variable to be easy to change later, or to avoid being redundant, or to save yourself a lot of typing for long type names like some_collection<some_type, some_other_template_argument>::difference_type.
That variable's type still needs to be known when it's declared, and C++ adds a further restriction that those variables need to be initialized when they're declared. Otherwise, it'd be more complicated for the compiler to figure out what type the variable's supposed to have, to say nothing of the programmers who have to read that code.
EDIT from the future: Repeater also brings up a good point about auto in templates. It's certainly a lot more pleasant to use auto there than having to decltype everything (or worse, add a new template parameter). Otherwise, there's a lot of uses for auto, including template<auto>, that I didn't really touch on.
I feel I should add to Albatross' comment that another, very valuable use of auto, is in templates. To my mind this is far more valuable than the other uses. It allows things that simply could not be done in previous version of C++.
@Repeater/TheDaemoness But I’ve tried to use auto for templates before, I thought it was illegal? I see what you mean though of course, I guess that was a fluke.
@dutch sorry, your right, I was just kinda responding. I’ll think next time.