使用lambda作为std :: cout的参数

Moh*_*d B 8 c++ lambda c++11

我正在尝试使用lambda,当测试以下时,编译说'hi'.

auto lmda = [](std::ostream& os) -> std::ostream& { os << "hi"; return os; };
std::cout << lmda;
Run Code Online (Sandbox Code Playgroud)

但是在添加捕获时,它不会编译.例:

std::vector<int> v(5, 3);
auto lmda = [&v](std::ostream& os) -> std::ostream& { os << v.size(); return os; };
std::cout << lmda;
Run Code Online (Sandbox Code Playgroud)

构建错误是:

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)
Run Code Online (Sandbox Code Playgroud)

我不明白为什么它在第二个例子中失败了.任何铅?

Sha*_*our 6

没有捕获的lambda 可以转换为函数指针,它将匹配以下重载:

basic_ostream& operator<<(
std::basic_ostream<CharT,Traits>& (*func)(std::basic_ostream<CharT,Traits>&) );
Run Code Online (Sandbox Code Playgroud)

正如cppreference链接说明:

调用func(*this);. 这些重载用于实现输出I/O操纵器,例如std :: endl.

来自草案C++ 11标准部分5.1.2 [expr.prim.lambda]:

没有lambda-capture的lambda表达式的闭包类型有一个公共的非虚拟非显式const转换函数,用于指向具有与闭包类型的函数调用操作符相同的参数和返回类型的函数.此转换函数返回的值应为函数的地址,该函数在调用时与调用闭包类型的函数调用运算符具有相同的效果