狠狠撸

狠狠撸Share a Scribd company logo
Effective Modern C++ #7Effective Modern C++ #7
2015/07/15
清?水超貴@simizut22
ちょっと?自?己紹介ちょっと?自?己紹介
清?水超貴(@simizut22)
数理計画がお仕事
基本荷物を積む
たまにグラフの対称性?見つける
やっぱり荷物を積む
closureclosureに変数をに変数をmovemoveするならするなら
初期化キャプチャ初期化キャプチャ――を使おうを使おう
変数を変数をmove capturemove captureしたいしたい
class Widget {
/* ... */
};
std::unique_ptr< Widget > pw;
auto fun = [pw]{ /* do something */ };
上記コード(compile 不可)
container などをcopyしたくない
などのとき
初期化キャプチャの構?文初期化キャプチャの構?文
value capture
reference capture
[ data = (expression) ]
[&data = (expression)]
auto cmp =
[eval = [](int i){ return -i;}] (int lhs, int rhs)
{ return eval(lhs) < eval(rhs);}
expression なので lambda を?入れるのももちろん可能
ちなみに,最新の gcc/msvc は次もok
http://melpon.org/wandbox/permlink/Gmqycg5tbA2iE51S
using iVec = std::vector< int >;
iVec data = iVec{1, 2, 3, 4, 5};
auto fun = [data{std::move(data)}]
{ std::copy(std::begin(data),
std::end(data),
[] () mutable
{ data.clear(): }};
prog.cc:9:19: warning:
direct list initialization of a lambda init-capture will change meaning in a future version of Cla
insert an '=' to avoid a change in behavior [-Wfuture-compat]
auto f = [data{ std::move(data) } ] {
^
clang だと次の messageが出る
ref:
N3681 Auto and Braced-Init-Lists
N3912 Atuto and Braced-Init-Lists, continued
N3922 New Rules for auto deduction from braced-init-list
template< class T >
struct wrap {
mutable T value_;
wrap(T&& v) : value_(std::forward< T >(v)) {}
wrap(wrap const& other) : value_(std::move(other.value_)) {}
};
struct Widget {};
auto pw = wrap< std::unique_ptr< Widget > >{std::make_unique< Widget >()};
auto fun = [pw]{ /* do something */ }
こんな wrapper を書くとか...
ref:N3610: Generic lambda-capture initializers
C++14 なら,初期化キャプチャーでできる
class Widget {
public:
/* ... */
bool isValidated() const;
bool isProessed() const;
bool isAchieved() const;
private:
/* ... */
};
auto pw = std::make_unique< Widget >();
/**
* configure *pw
**/
auto func = [pw = std::move(pw)]
{ return pw->isValidated()
&& pw->isAchived();};
/**
* pw is moved to data member pw of closure
**/
こうなる
上記のコードでは
1. closureにデータメンバー pw を作成して
2. local 変数 pw を move して
3. メンバーpw を初期化
をやっている
[pw = std::move(pw)] { /* do something */};
もし con?gure pw の操作が不要なら,
初期化を capture と同時にやればよい
[pw = std::make_unique< Widget >()] () { /* do something */ };
lambdalambda 使わなくていいならクラス書けば解決で使わなくていいならクラス書けば解決で
きるきるclass Widget {
/* same as before */
};
class IsValAndArch {
public:
using DataType = std::unique_ptr< Widget >;
explicit IsValAndArch(DataType&& dt)
: pw(std::move(dt)) {}
bool operator()() const {
return pw->isValid()
&& pw->isArchived();
}
private:
DataType pw;
};
auto func = IsValAndArch{ std::unique_ptr< Widget >{new Widget()}};
// auto func = IsValAndArch{ std::make_unique< Widget >() };
疲れる.やっぱり lambda 使いたい...
それそれ bindbind でできるよでできるよ!!!!
1. (move)キャプチャーしたい変数を bind object 内にmoveする
2. "キャプチャー"した変数の参照をラムダの引数にする
をすればよい
/** c++ 14 init capture **/
using dVec =
std::vector< double >;
dVec data;
/* configure data */
auto func =
[data = std::move(data)]
{ /* do somthing */ };
/** use std::bind for c++11 **/
using dVec =
std::vector< double >;
dVec data;
/* configure data */
auto func =
std::bind([](dVec const&)
// (2) ^^^^^^^^^^^^
{/* do somthing */}
, std::move(data));
// (1) ^^^^^^^^^^^^^^^
具体的なコードは以下
bindbind とと closureclosure の違いの違い
/** c++ 14 init capture **/
std::vector< double > data;
/* cofigure data */
auto func =
[data = std::move(data)]
{ data.clear() };
/** bind version **/
std::vector< double > data;
/** config data **/
auto func =
std::bind([](std::vector< double > v&)
{ v.clear(); }
, std::move(data));
これを愚直に書き換えると
http://melpon.org/wandbox/permlink/3bIhkKfDDlQhXREr
Start
prog.cc:7:19: error: member function 'clear' not viable: 'this' argument has type 'const std::__1:
{ data.clear(); };
^~~~
/usr/local/libcxx-head/include/c++/v1/vector:735:10: note: 'clear' declared here
void clear() _NOEXCEPT
^
1 error generated.
clang3.7.0
build してみた
ClosureType::operator() は
デフォルトではconst method
mutable speci?er を付けると non-const method
が呼ばれる(上は const method を呼んでる)
auto fun = [data = std::move(data)] () mutable
{ data.clear(); }; // ^^^^^^^
これで?大丈夫!(^^)!
** mutable を付けるときには argument parameter list が必要
http://melpon.org/wandbox/permlink/zzoa3WK54NxBz7Ac
bind object の?生存期間
auto makeFun() // sorry this is c++14
{
std::vector< int > data{1,2,3,4,5};
auto fun = [](const std::vector< int >& v)
{ std::copy(v.begin(), v.end(),
std::ostream_iterator< int >(std::cout, " "));};
return std::bind(fun, std::move(data)); // data is copied in bind obj
}
auto&& fun = makeFun();
fun(); // ok
先に述べた bind + lambda を?用いた?方法を使った時
bind object の?生存期間
= closure object(?rst argument )の?生存期間
= move "capture" された data の?生存期間
がなりたつ
従って,capture された data を closure から呼ぶことに問題はない
1. c++11 lambda では closure に move-construct はできないけど,
bind object にはできる
2. bind-object 内に move-construct してから,lambda に参照渡し
することで move キャプチャを模倣できる
3. 上記?方法では bind-object の寿命と closure の寿命が同じなの
で, move されたデータはキャプチャされたように扱える
bindbind によるによる init captureinit capture の模倣の要の模倣の要
点点
* ここまでやったけど Item34 では bind より lambda の?方がいいという話をする
Things to RememberThings to Remember
closure 内に objects を move するなら c++14 init
capture を使おう
直にクラスを書くか bind を使えば init-capture は
emulate できる
Ad

Recommended

Emcpp item31
Emcpp item31
mitsutaka_takeda
?
Emcpp0506
Emcpp0506
Takatoshi Kondo
?
Effective modern c++ 8
Effective modern c++ 8
uchan_nos
?
Effective Modern C++ 勉強会#3 Item 15
Effective Modern C++ 勉強会#3 Item 15
Mitsuru Kariya
?
迟别尘辫濒补迟别と补耻迟辞の型推论
迟别尘辫濒补迟别と补耻迟辞の型推论
MITSUNARI Shigeo
?
Effective modern c++ 5
Effective modern c++ 5
uchan_nos
?
Increment and Decrement operators in C++
Increment and Decrement operators in C++
Neeru Mittal
?
Effective Modern C++ 勉強会#1 Item3,4
Effective Modern C++ 勉強会#1 Item3,4
Takashi Hoshino
?
C#や.NET Frameworkがやっていること
C#や.NET Frameworkがやっていること
信之 岩永
?
Effective Modern C++勉強会#4 Item 17, 18資料
Effective Modern C++勉強会#4 Item 17, 18資料
Ryo Igarashi
?
Unit II chapter 4 Loops in C
Unit II chapter 4 Loops in C
Sowmya Jyothi
?
Understand more about C
Understand more about C
Yi-Hsiu Hsu
?
C++ Programming Language
C++ Programming Language
Mohamed Loey
?
GDB Rocks!
GDB Rocks!
Kent Chen
?
OOP in C++
OOP in C++
ppd1961
?
Deep C
Deep C
Olve Maudal
?
How A Compiler Works: GNU Toolchain
How A Compiler Works: GNU Toolchain
National Cheng Kung University
?
Q2.12: Debugging with GDB
Q2.12: Debugging with GDB
Linaro
?
Shell scripting
Shell scripting
Geeks Anonymes
?
やさしく知りたい颁言语
やさしく知りたい颁言语
uru nru
?
Sigreturn Oriented Programming
Sigreturn Oriented Programming
Angel Boy
?
Constructor
Constructor
poonamchopra7975
?
颁言语超入门
颁言语超入门
Mercury Soft
?
effective modern c++ chapeter36
effective modern c++ chapeter36
Tatsuki SHIMIZU
?
Introduction to gdb
Introduction to gdb
Owen Hsu
?
Shell Scripting
Shell Scripting
Gaurav Shinde
?
Telephone directory using c language
Telephone directory using c language
Mauryasuraj98
?
Effective Modern C++ 勉強会 Item26
Effective Modern C++ 勉強会 Item26
Akihiro Nishimura
?
Effective modern C++ 勉強会 #3 Item 12
Effective modern C++ 勉強会 #3 Item 12
Keisuke Fukuda
?
Effective Modern C++ 勉強会#3 Item16
Effective Modern C++ 勉強会#3 Item16
Mitsuru Kariya
?

More Related Content

What's hot (20)

C#や.NET Frameworkがやっていること
C#や.NET Frameworkがやっていること
信之 岩永
?
Effective Modern C++勉強会#4 Item 17, 18資料
Effective Modern C++勉強会#4 Item 17, 18資料
Ryo Igarashi
?
Unit II chapter 4 Loops in C
Unit II chapter 4 Loops in C
Sowmya Jyothi
?
Understand more about C
Understand more about C
Yi-Hsiu Hsu
?
C++ Programming Language
C++ Programming Language
Mohamed Loey
?
GDB Rocks!
GDB Rocks!
Kent Chen
?
OOP in C++
OOP in C++
ppd1961
?
Deep C
Deep C
Olve Maudal
?
How A Compiler Works: GNU Toolchain
How A Compiler Works: GNU Toolchain
National Cheng Kung University
?
Q2.12: Debugging with GDB
Q2.12: Debugging with GDB
Linaro
?
Shell scripting
Shell scripting
Geeks Anonymes
?
やさしく知りたい颁言语
やさしく知りたい颁言语
uru nru
?
Sigreturn Oriented Programming
Sigreturn Oriented Programming
Angel Boy
?
Constructor
Constructor
poonamchopra7975
?
颁言语超入门
颁言语超入门
Mercury Soft
?
effective modern c++ chapeter36
effective modern c++ chapeter36
Tatsuki SHIMIZU
?
Introduction to gdb
Introduction to gdb
Owen Hsu
?
Shell Scripting
Shell Scripting
Gaurav Shinde
?
Telephone directory using c language
Telephone directory using c language
Mauryasuraj98
?
Effective Modern C++ 勉強会 Item26
Effective Modern C++ 勉強会 Item26
Akihiro Nishimura
?
C#や.NET Frameworkがやっていること
C#や.NET Frameworkがやっていること
信之 岩永
?
Effective Modern C++勉強会#4 Item 17, 18資料
Effective Modern C++勉強会#4 Item 17, 18資料
Ryo Igarashi
?
Unit II chapter 4 Loops in C
Unit II chapter 4 Loops in C
Sowmya Jyothi
?
Understand more about C
Understand more about C
Yi-Hsiu Hsu
?
C++ Programming Language
C++ Programming Language
Mohamed Loey
?
Q2.12: Debugging with GDB
Q2.12: Debugging with GDB
Linaro
?
やさしく知りたい颁言语
やさしく知りたい颁言语
uru nru
?
Sigreturn Oriented Programming
Sigreturn Oriented Programming
Angel Boy
?
effective modern c++ chapeter36
effective modern c++ chapeter36
Tatsuki SHIMIZU
?
Introduction to gdb
Introduction to gdb
Owen Hsu
?
Telephone directory using c language
Telephone directory using c language
Mauryasuraj98
?
Effective Modern C++ 勉強会 Item26
Effective Modern C++ 勉強会 Item26
Akihiro Nishimura
?

Viewers also liked (15)

Effective modern C++ 勉強会 #3 Item 12
Effective modern C++ 勉強会 #3 Item 12
Keisuke Fukuda
?
Effective Modern C++ 勉強会#3 Item16
Effective Modern C++ 勉強会#3 Item16
Mitsuru Kariya
?
Effective modern-c++#9
Effective modern-c++#9
Tatsuki SHIMIZU
?
Effective Modern C++ 勉強会#7 Item 27
Effective Modern C++ 勉強会#7 Item 27
Mitsuru Kariya
?
Effective Modern C++ study group Item39
Effective Modern C++ study group Item39
Takatoshi Kondo
?
Effective Modern C++ 勉強会 Item 22
Effective Modern C++ 勉強会 Item 22
Keisuke Fukuda
?
Effective Modern C++勉強会#2 Item 11(,12)
Effective Modern C++勉強会#2 Item 11(,12)
Keisuke Fukuda
?
Effective Modern C++ 勉強会#6 Item25
Effective Modern C++ 勉強会#6 Item25
Takashi Hoshino
?
Effective Modern C++ 勉強会#8 Item38
Effective Modern C++ 勉強会#8 Item38
Takashi Hoshino
?
Effective Modern C++ Item 24: Distinguish universal references from rvalue re...
Effective Modern C++ Item 24: Distinguish universal references from rvalue re...
mooopan
?
Emcjp item33,34
Emcjp item33,34
MITSUNARI Shigeo
?
emcjp Item 42
emcjp Item 42
MITSUNARI Shigeo
?
Emcjp item21
Emcjp item21
MITSUNARI Shigeo
?
Emcpp item41
Emcpp item41
mitsutaka_takeda
?
Effective Modern C++ 読書会 Item 35
Effective Modern C++ 読書会 Item 35
Keisuke Fukuda
?
Effective modern C++ 勉強会 #3 Item 12
Effective modern C++ 勉強会 #3 Item 12
Keisuke Fukuda
?
Effective Modern C++ 勉強会#3 Item16
Effective Modern C++ 勉強会#3 Item16
Mitsuru Kariya
?
Effective Modern C++ 勉強会#7 Item 27
Effective Modern C++ 勉強会#7 Item 27
Mitsuru Kariya
?
Effective Modern C++ study group Item39
Effective Modern C++ study group Item39
Takatoshi Kondo
?
Effective Modern C++ 勉強会 Item 22
Effective Modern C++ 勉強会 Item 22
Keisuke Fukuda
?
Effective Modern C++勉強会#2 Item 11(,12)
Effective Modern C++勉強会#2 Item 11(,12)
Keisuke Fukuda
?
Effective Modern C++ 勉強会#6 Item25
Effective Modern C++ 勉強会#6 Item25
Takashi Hoshino
?
Effective Modern C++ 勉強会#8 Item38
Effective Modern C++ 勉強会#8 Item38
Takashi Hoshino
?
Effective Modern C++ Item 24: Distinguish universal references from rvalue re...
Effective Modern C++ Item 24: Distinguish universal references from rvalue re...
mooopan
?
Effective Modern C++ 読書会 Item 35
Effective Modern C++ 読書会 Item 35
Keisuke Fukuda
?
Ad

Similar to emc++ chapter32 (20)

T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門
伸男 伊藤
?
颁++コミュニティーの中心で颁++を顿滨厂る
颁++コミュニティーの中心で颁++を顿滨厂る
Hideyuki Tanaka
?
C++0x 言語の未来を語る
C++0x 言語の未来を語る
Akira Takahashi
?
クロージャデザインパターン
クロージャデザインパターン
Moriharu Ohzu
?
C++0x in programming competition
C++0x in programming competition
yak1ex
?
Effective Modern C++ Item 7&8
Effective Modern C++ Item 7&8
明 高橋
?
C++ tips4 cv修飾編
C++ tips4 cv修飾編
道化師 堂華
?
ぱっと见でわかる颁++11
ぱっと见でわかる颁++11
えぴ 福田
?
Move semantics
Move semantics
mitsutaka_takeda
?
わんくま同盟大阪勉强会#61
わんくま同盟大阪勉强会#61
TATSUYA HAYAMIZU
?
C++ lecture-1
C++ lecture-1
sunaemon
?
Boost.PropertyMap (.pdf)
Boost.PropertyMap (.pdf)
Cryolite
?
Boost.PropertyMap (.pptx)
Boost.PropertyMap (.pptx)
Cryolite
?
これから Haskell を書くにあたって
これから Haskell を書くにあたって
Tsuyoshi Matsudate
?
C++11概要 ライブラリ編
C++11概要 ライブラリ編
egtra
?
Haskell Lecture 2
Haskell Lecture 2
Yusuke Matsushita
?
2016年第二回プレ卒研颈苍山口研
2016年第二回プレ卒研颈苍山口研
dmcc2015
?
T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門
伸男 伊藤
?
颁++コミュニティーの中心で颁++を顿滨厂る
颁++コミュニティーの中心で颁++を顿滨厂る
Hideyuki Tanaka
?
C++0x 言語の未来を語る
C++0x 言語の未来を語る
Akira Takahashi
?
クロージャデザインパターン
クロージャデザインパターン
Moriharu Ohzu
?
C++0x in programming competition
C++0x in programming competition
yak1ex
?
Effective Modern C++ Item 7&8
Effective Modern C++ Item 7&8
明 高橋
?
ぱっと见でわかる颁++11
ぱっと见でわかる颁++11
えぴ 福田
?
わんくま同盟大阪勉强会#61
わんくま同盟大阪勉强会#61
TATSUYA HAYAMIZU
?
C++ lecture-1
C++ lecture-1
sunaemon
?
Boost.PropertyMap (.pdf)
Boost.PropertyMap (.pdf)
Cryolite
?
Boost.PropertyMap (.pptx)
Boost.PropertyMap (.pptx)
Cryolite
?
これから Haskell を書くにあたって
これから Haskell を書くにあたって
Tsuyoshi Matsudate
?
C++11概要 ライブラリ編
C++11概要 ライブラリ編
egtra
?
2016年第二回プレ卒研颈苍山口研
2016年第二回プレ卒研颈苍山口研
dmcc2015
?
Ad

More from Tatsuki SHIMIZU (17)

ロマ数16 simizut
ロマ数16 simizut
Tatsuki SHIMIZU
?
Magnitude ~ extend the Euler Characteristics via M?bius Inversion ~
Magnitude ~ extend the Euler Characteristics via M?bius Inversion ~
Tatsuki SHIMIZU
?
TDA やら Night!!
TDA やら Night!!
Tatsuki SHIMIZU
?
Introduction to Persistence Theory
Introduction to Persistence Theory
Tatsuki SHIMIZU
?
エキゾチック球面ナイト(浮気編)~28 日周期の彼女たち~
エキゾチック球面ナイト(浮気編)~28 日周期の彼女たち~
Tatsuki SHIMIZU
?
Practical topology
Practical topology
Tatsuki SHIMIZU
?
Euler 標数は測度ですか??
Euler 標数は測度ですか??
Tatsuki SHIMIZU
?
Operad and Recognition Principle
Operad and Recognition Principle
Tatsuki SHIMIZU
?
しかくのお勉强
しかくのお勉强
Tatsuki SHIMIZU
?
Packing
Packing
Tatsuki SHIMIZU
?
Introduction to Topological Data Analysis
Introduction to Topological Data Analysis
Tatsuki SHIMIZU
?
情報幾何学の基礎 第2章 4.5
情報幾何学の基礎 第2章 4.5
Tatsuki SHIMIZU
?
Jules henri poincaré
Jules henri poincaré
Tatsuki SHIMIZU
?
情報幾何の基礎輪読会 #1
情報幾何の基礎輪読会 #1
Tatsuki SHIMIZU
?
introductino to persistent homology and topological data analysis
introductino to persistent homology and topological data analysis
Tatsuki SHIMIZU
?
代数トポロジー入门
代数トポロジー入门
Tatsuki SHIMIZU
?
topology of musical data
topology of musical data
Tatsuki SHIMIZU
?
Magnitude ~ extend the Euler Characteristics via M?bius Inversion ~
Magnitude ~ extend the Euler Characteristics via M?bius Inversion ~
Tatsuki SHIMIZU
?
Introduction to Persistence Theory
Introduction to Persistence Theory
Tatsuki SHIMIZU
?
エキゾチック球面ナイト(浮気編)~28 日周期の彼女たち~
エキゾチック球面ナイト(浮気編)~28 日周期の彼女たち~
Tatsuki SHIMIZU
?
Euler 標数は測度ですか??
Euler 標数は測度ですか??
Tatsuki SHIMIZU
?
Operad and Recognition Principle
Operad and Recognition Principle
Tatsuki SHIMIZU
?
Introduction to Topological Data Analysis
Introduction to Topological Data Analysis
Tatsuki SHIMIZU
?
情報幾何学の基礎 第2章 4.5
情報幾何学の基礎 第2章 4.5
Tatsuki SHIMIZU
?
情報幾何の基礎輪読会 #1
情報幾何の基礎輪読会 #1
Tatsuki SHIMIZU
?
introductino to persistent homology and topological data analysis
introductino to persistent homology and topological data analysis
Tatsuki SHIMIZU
?
代数トポロジー入门
代数トポロジー入门
Tatsuki SHIMIZU
?

emc++ chapter32

  • 1. Effective Modern C++ #7Effective Modern C++ #7 2015/07/15 清?水超貴@simizut22
  • 4. 変数を変数をmove capturemove captureしたいしたい class Widget { /* ... */ }; std::unique_ptr< Widget > pw; auto fun = [pw]{ /* do something */ }; 上記コード(compile 不可) container などをcopyしたくない などのとき
  • 5. 初期化キャプチャの構?文初期化キャプチャの構?文 value capture reference capture [ data = (expression) ] [&data = (expression)] auto cmp = [eval = [](int i){ return -i;}] (int lhs, int rhs) { return eval(lhs) < eval(rhs);} expression なので lambda を?入れるのももちろん可能
  • 6. ちなみに,最新の gcc/msvc は次もok http://melpon.org/wandbox/permlink/Gmqycg5tbA2iE51S using iVec = std::vector< int >; iVec data = iVec{1, 2, 3, 4, 5}; auto fun = [data{std::move(data)}] { std::copy(std::begin(data), std::end(data), [] () mutable { data.clear(): }}; prog.cc:9:19: warning: direct list initialization of a lambda init-capture will change meaning in a future version of Cla insert an '=' to avoid a change in behavior [-Wfuture-compat] auto f = [data{ std::move(data) } ] { ^ clang だと次の messageが出る ref: N3681 Auto and Braced-Init-Lists N3912 Atuto and Braced-Init-Lists, continued N3922 New Rules for auto deduction from braced-init-list
  • 7. template< class T > struct wrap { mutable T value_; wrap(T&& v) : value_(std::forward< T >(v)) {} wrap(wrap const& other) : value_(std::move(other.value_)) {} }; struct Widget {}; auto pw = wrap< std::unique_ptr< Widget > >{std::make_unique< Widget >()}; auto fun = [pw]{ /* do something */ } こんな wrapper を書くとか... ref:N3610: Generic lambda-capture initializers C++14 なら,初期化キャプチャーでできる
  • 8. class Widget { public: /* ... */ bool isValidated() const; bool isProessed() const; bool isAchieved() const; private: /* ... */ }; auto pw = std::make_unique< Widget >(); /** * configure *pw **/ auto func = [pw = std::move(pw)] { return pw->isValidated() && pw->isAchived();}; /** * pw is moved to data member pw of closure **/ こうなる
  • 9. 上記のコードでは 1. closureにデータメンバー pw を作成して 2. local 変数 pw を move して 3. メンバーpw を初期化 をやっている [pw = std::move(pw)] { /* do something */}; もし con?gure pw の操作が不要なら, 初期化を capture と同時にやればよい [pw = std::make_unique< Widget >()] () { /* do something */ };
  • 10. lambdalambda 使わなくていいならクラス書けば解決で使わなくていいならクラス書けば解決で きるきるclass Widget { /* same as before */ }; class IsValAndArch { public: using DataType = std::unique_ptr< Widget >; explicit IsValAndArch(DataType&& dt) : pw(std::move(dt)) {} bool operator()() const { return pw->isValid() && pw->isArchived(); } private: DataType pw; }; auto func = IsValAndArch{ std::unique_ptr< Widget >{new Widget()}}; // auto func = IsValAndArch{ std::make_unique< Widget >() }; 疲れる.やっぱり lambda 使いたい...
  • 11. それそれ bindbind でできるよでできるよ!!!! 1. (move)キャプチャーしたい変数を bind object 内にmoveする 2. "キャプチャー"した変数の参照をラムダの引数にする をすればよい /** c++ 14 init capture **/ using dVec = std::vector< double >; dVec data; /* configure data */ auto func = [data = std::move(data)] { /* do somthing */ }; /** use std::bind for c++11 **/ using dVec = std::vector< double >; dVec data; /* configure data */ auto func = std::bind([](dVec const&) // (2) ^^^^^^^^^^^^ {/* do somthing */} , std::move(data)); // (1) ^^^^^^^^^^^^^^^ 具体的なコードは以下
  • 12. bindbind とと closureclosure の違いの違い /** c++ 14 init capture **/ std::vector< double > data; /* cofigure data */ auto func = [data = std::move(data)] { data.clear() }; /** bind version **/ std::vector< double > data; /** config data **/ auto func = std::bind([](std::vector< double > v&) { v.clear(); } , std::move(data)); これを愚直に書き換えると
  • 13. http://melpon.org/wandbox/permlink/3bIhkKfDDlQhXREr Start prog.cc:7:19: error: member function 'clear' not viable: 'this' argument has type 'const std::__1: { data.clear(); }; ^~~~ /usr/local/libcxx-head/include/c++/v1/vector:735:10: note: 'clear' declared here void clear() _NOEXCEPT ^ 1 error generated. clang3.7.0 build してみた ClosureType::operator() は デフォルトではconst method mutable speci?er を付けると non-const method が呼ばれる(上は const method を呼んでる) auto fun = [data = std::move(data)] () mutable { data.clear(); }; // ^^^^^^^ これで?大丈夫!(^^)! ** mutable を付けるときには argument parameter list が必要 http://melpon.org/wandbox/permlink/zzoa3WK54NxBz7Ac
  • 14. bind object の?生存期間 auto makeFun() // sorry this is c++14 { std::vector< int > data{1,2,3,4,5}; auto fun = [](const std::vector< int >& v) { std::copy(v.begin(), v.end(), std::ostream_iterator< int >(std::cout, " "));}; return std::bind(fun, std::move(data)); // data is copied in bind obj } auto&& fun = makeFun(); fun(); // ok 先に述べた bind + lambda を?用いた?方法を使った時 bind object の?生存期間 = closure object(?rst argument )の?生存期間 = move "capture" された data の?生存期間 がなりたつ 従って,capture された data を closure から呼ぶことに問題はない
  • 15. 1. c++11 lambda では closure に move-construct はできないけど, bind object にはできる 2. bind-object 内に move-construct してから,lambda に参照渡し することで move キャプチャを模倣できる 3. 上記?方法では bind-object の寿命と closure の寿命が同じなの で, move されたデータはキャプチャされたように扱える bindbind によるによる init captureinit capture の模倣の要の模倣の要 点点 * ここまでやったけど Item34 では bind より lambda の?方がいいという話をする
  • 16. Things to RememberThings to Remember closure 内に objects を move するなら c++14 init capture を使おう 直にクラスを書くか bind を使えば init-capture は emulate できる