简体   繁体   中英

Using lambda as parameter to std::cout

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 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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM