2015-10-23 8 views
7

ラムダの使用を実験しており、以下のテストでは 'hi'とコンパイルします。ラムダをstd :: coutのパラメータとして使用する

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

ただし、キャプチャを追加するとコンパイルされません。 例:

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

ビルドエラーは次のとおりです。

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) 

それは第二の例では失敗した理由を、私は得ることはありません。 いずれのリードですか?

答えて

5

following overload一致しますラムダwithout a capture is convertible to a function pointer:cppreferenceはノートリンクとして

basic_ostream& operator<<(
std::basic_ostream<CharT,Traits>& (*func)(std::basic_ostream<CharT,Traits>&)); 

を:

コールfuncを(*この);。これらのオーバーロードは、std :: endlなどの出力I/O マニピュレータを実装するために使用されます。

ドラフトC++ 11標準セクション5.1.2[expr.prim.lambda]から:

ないラムダキャプチャとラムダ式ための閉鎖型は 公開有します非仮想非明示的なconst変換関数 をと同じパラメータを持ち、戻り値の型はクロージャ 型の関数呼び出し演算子と同じです。この変換 関数によって返される値は

+0

注:この過負荷は、 'std :: endl'や' std :: boolalpha'のようなマニピュレータが機能するように存在します。オーバーロードされた '<<'演算子を使って 'struct'を実行しただけで、後で知ることができます。 – Simple

+0

@簡単なポイント、それは私が含まれているが、答えを追加したcppreferenceリンクに記載されていた。 –

0

ストリームを受け入れ、それを使用して同じストリームを返す関数を定義しています。

ことの可能な用途は次のとおりです。

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

ない捕獲とラムダはpointer-に変換され、呼び出されたときに、閉鎖型の関数呼び出し演算子を呼び出すよう 同じ効果を持つ関数のアドレスでなければなりません機能する。

[5.1.2/6]ないラムダキャプチャ非ジェネリックラムダ発現のため閉鎖型はC++言語で関数へのポインタ、公開非仮想非明示的なconstの変換機能を有しています同じ接頭辞型の関数呼び出し演算子として戻り値の型を持つ連結(7.5)。この変換関数によって返される値は、呼び出されたときにクロージャ 型の関数呼び出し演算子を呼び出すのと同じ効果を持つ関数のアドレスとする。

キャプチャによるラムダは印刷可能なものに変換できません。

関連する問題