hack のためのネタ帳, etc,,,

×

参考になるページ等

雑記

変数のキャプチャと lambda の参照渡し

g++ 4.8.2 で試してみたところ
以下のように変数がキャプチャされてると lambda の参照渡しが上手く出来ない
普通、関数オブジェクトは参照渡ししたいから、共通のルーチンが使えなくて困る気がする。
一旦変数に格納すると参照渡しは可能な模様。
#include <iostream>

template < typename Func >
inline void f_with_ref( Func &func )
{
  func() ;
}
template < typename Func >
inline void f_with_cpy( Func func )
{
  func() ;
}

int main()
{
  int x = 1;
  auto f =      [&]         {std::cout << "lambda with ref capture" << x << std::endl;};
  //f_with_ref( [ ]         {std::cout << "lambda with non capture" << 1 << std::endl;}); // invalid initialization of non-const reference of type lambda& from an rvalue of type lambda
  ; f_with_cpy(*[ ]         {std::cout << "lambda with non capture" << 1 << std::endl;}); 
  ; f_with_ref(*[ ]         {std::cout << "lambda with non capture" << 1 << std::endl;}); 
  ; f_with_cpy( [ ]         {std::cout << "lambda with non capture" << 1 << std::endl;}); 
  ; f_with_ref(*[&]         {std::cout << "lambda with non capture" << 1 << std::endl;}); 
  ; f_with_cpy( [&]         {std::cout << "lambda with non capture" << 1 << std::endl;}); 
  //f_with_ref(*[&]         {std::cout << "lambda with ref capture" << x << std::endl;});  // no match for operator* (operand type is lambda)
  ; f_with_cpy( [&]         {std::cout << "lambda with ref capture" << x << std::endl;}); 
  //f_with_ref(*[=]()mutable{std::cout << "lambda with cpy capture" << x << std::endl;});  //no match for operator* (operand type is lambda)
  ; f_with_cpy( [=]()mutable{std::cout << "lambda with cpy capture" << x << std::endl;}); 
  ; f_with_ref( f                                                                      ); 
  ; f_with_cpy( f                                                                      ); 
}
コンパイルは、-std=c++11 か gnu++11 付けとかないと auto のところで失敗した。

良く調べてみると STL の for_each なんかも普通にコピー渡ししてた。
関数オブジェクト使って Sum みたいなことしようとした場合に、コピー渡しだと使い難いと思うんだが、STL でさえそうしてるということは、何かしらやんごとない事情ががあるんだろうな、きっと。

関連

タグ

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Wiki内検索

フリーエリア

管理人/副管理人のみ編集できます