I am experimenting with lambda use and when testing the following it compile say 'hi'.
auto lmda = [](std::ostream& os) -> std::ostream& { os << "hi"; return os; };
std::cout << lmda;
But when adding capture, it does not compile. Example:
std::vector<int> v(5, 3);
auto lmda = [&v](std::ostream& os) -> std::ostream& { os << v.size(); return os; };
std::cout << lmda;
Build error is:
In function 'int main()':
10:18: error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'
In file included from /usr/include/c++/4.9/iostream:39:0,
from 2:
/usr/include/c++/4.9/ostream:602:5: note: initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = main()::<lambda(std::ostream&)>]'
operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
I don't get why it fails in the second example. Any lead?
A lambda is also just a function object, so you need to have a () to call it, there is no way around it (except of course some function that invokes the lambda like std::invoke ). If you want you can drop the () after the capture list, because your lambda doesn't take any parameters.
Instances of std::function can store, copy, and invoke any CopyConstructible Callable target -- functions, lambda expressions, bind expressions, or other function objects, as well as pointers to member functions and pointers to data members.
Lambdas can both capture variables and accept input parameters. A parameter list (lambda declarator in the Standard syntax) is optional and in most aspects resembles the parameter list for a function. auto y = [] (int first, int second) { return first + second; };
Lambda's type One important thing to note is that a lambda is not a std::function .
The simplest way is to use std::function as a function parameter. This would allow you to pass a function object or a lambda to the function. Does the C++ standard require that the type of a lambda expression with no captures be a function pointer or convertible to a function pointer?
Using Lambda Expressions with Managed Types (C++/CLI) Example. The capture clause of a lambda expression cannot contain a variable that has a managed type. However, you can pass an argument that has a managed type to the parameter list of a lambda expression.
If the lambda body contains one return statement, the compiler deduces the return type from the type of the return expression. Otherwise, the compiler deduces the return type as void.
If the lambda does not capture any variables and you want a function pointer, it can be done; details are given at C++ | Converting captureless generic lambda to function pointers. If it does capture variables, and you want a function pointer, that just isn’t happening; capturing lambdas cannot be converted to functions.
A lambda without a capture is convertible to a function pointer which will match the following overload:
basic_ostream& operator<<(
std::basic_ostream<CharT,Traits>& (*func)(std::basic_ostream<CharT,Traits>&) );
As the cppreference links notes:
Calls func(*this);. These overloads are used to implement output I/O manipulators such as std::endl.
from the draft C++11 standard section 5.1.2
[expr.prim.lambda]:
The closure type for a lambda-expression with no lambda-capture has a public non-virtual non-explicit const conversion function to pointer to function having the same parameter and return types as the closure type’s function call operator. The value returned by this conversion function shall be the address of a function that, when invoked, has the same effect as invoking the closure type’s function call operator
A lambda with no capture is convertible to a pointer-to-function.
[5.1.2/6] The closure type for a non-generic lambda-expression with no lambda-capture has a public non-virtual non-explicit const conversion function to pointer to function with C ++ language linkage (7.5) having the same parameter and return types as the closure type’s function call operator. The value returned by this conversion function shall be the address of a function that, when invoked, has the same effect as invoking the closure type’s function call operator.
A lambda with capture is not convertible to anything printable.
You are defining a function that accepts a stream, uses it and then return the same stream.
A possible use of it follows:
#include <functional>
#include <iostream>
#include <vector>
int main() {
std::vector<int> v(5, 3);
auto lmda = [&v](std::ostream& os) -> std::ostream& { os << v.size(); return os; };
lmda(std::cout) << std::endl;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With