Submit Search
Upload
Emcpp item31
•
3 likes
•
10,917 views
M
mitsutaka_takeda
Follow
Effective Modern C++勉強会用資料 https://atnd.org/events/67443
Read less
Read more
Software
Report
Share
Report
Share
1 of 25
Download now
Download to read offline
Recommended
emc++ chapter32
emc++ chapter32
Tatsuki SHIMIZU
Effective modern c++ 5
Effective modern c++ 5
uchan_nos
Effective modern c++ 8
Effective modern c++ 8
uchan_nos
Emcpp0506
Emcpp0506
Takatoshi Kondo
effective modern c++ chapeter36
effective modern c++ chapeter36
Tatsuki SHIMIZU
Effective Modern C++ Item 9 and 10
Effective Modern C++ Item 9 and 10
uchan_nos
Effective Modern C++ 勉強会#1 Item3,4
Effective Modern C++ 勉強会#1 Item3,4
Takashi Hoshino
Emcjp item21
Emcjp item21
MITSUNARI Shigeo
Recommended
emc++ chapter32
emc++ chapter32
Tatsuki SHIMIZU
Effective modern c++ 5
Effective modern c++ 5
uchan_nos
Effective modern c++ 8
Effective modern c++ 8
uchan_nos
Emcpp0506
Emcpp0506
Takatoshi Kondo
effective modern c++ chapeter36
effective modern c++ chapeter36
Tatsuki SHIMIZU
Effective Modern C++ Item 9 and 10
Effective Modern C++ Item 9 and 10
uchan_nos
Effective Modern C++ 勉強会#1 Item3,4
Effective Modern C++ 勉強会#1 Item3,4
Takashi Hoshino
Emcjp item21
Emcjp item21
MITSUNARI Shigeo
Effective Modern C++勉強会#4 Item 17, 18資料
Effective Modern C++勉強会#4 Item 17, 18資料
Ryo Igarashi
Effective Modern C++ 勉強会#3 Item16
Effective Modern C++ 勉強会#3 Item16
Mitsuru Kariya
Effective Modern C++ 勉強会#3 Item 15
Effective Modern C++ 勉強会#3 Item 15
Mitsuru Kariya
Effective Modern C++ 勉強会#7 Item 27
Effective Modern C++ 勉強会#7 Item 27
Mitsuru Kariya
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
kikairoya
templateとautoの型推論
templateとautoの型推論
MITSUNARI Shigeo
クソザコ鳥頭が非順序連想コンテナに入門してみた
クソザコ鳥頭が非順序連想コンテナに入門してみた
Mitsuru Kariya
unique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるとき
Shintarou Okada
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30
Chris Ohk
Visual C++で使えるC++11
Visual C++で使えるC++11
nekko1119
C++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプ
Kohsuke Yuasa
良い?悪い?コードコメントの書き方
良い?悪い?コードコメントの書き方
Shigenori Sagawa
すごいConstたのしく使おう!
すごいConstたのしく使おう!
Akihiro Nishimura
クロージャデザインパターン
クロージャデザインパターン
Moriharu Ohzu
PWNの超入門 大和セキュリティ神戸 2018-03-25
PWNの超入門 大和セキュリティ神戸 2018-03-25
Isaac Mathis
Visual C++コード分析を支えるSAL
Visual C++コード分析を支えるSAL
egtra
C++の話(本当にあった怖い話)
C++の話(本当にあった怖い話)
Yuki Tamura
「日本語LaTeX」が多すぎる件について
「日本語LaTeX」が多すぎる件について
Takayuki Yato
Effective Modern C++ 勉強会 Item26
Effective Modern C++ 勉強会 Item26
Akihiro Nishimura
LR parsing
LR parsing
ichikaz3
C++ lecture-1
C++ lecture-1
sunaemon
Boost Tour 1.50.0 All
Boost Tour 1.50.0 All
Akira Takahashi
More Related Content
What's hot
Effective Modern C++勉強会#4 Item 17, 18資料
Effective Modern C++勉強会#4 Item 17, 18資料
Ryo Igarashi
Effective Modern C++ 勉強会#3 Item16
Effective Modern C++ 勉強会#3 Item16
Mitsuru Kariya
Effective Modern C++ 勉強会#3 Item 15
Effective Modern C++ 勉強会#3 Item 15
Mitsuru Kariya
Effective Modern C++ 勉強会#7 Item 27
Effective Modern C++ 勉強会#7 Item 27
Mitsuru Kariya
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
kikairoya
templateとautoの型推論
templateとautoの型推論
MITSUNARI Shigeo
クソザコ鳥頭が非順序連想コンテナに入門してみた
クソザコ鳥頭が非順序連想コンテナに入門してみた
Mitsuru Kariya
unique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるとき
Shintarou Okada
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30
Chris Ohk
Visual C++で使えるC++11
Visual C++で使えるC++11
nekko1119
C++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプ
Kohsuke Yuasa
良い?悪い?コードコメントの書き方
良い?悪い?コードコメントの書き方
Shigenori Sagawa
すごいConstたのしく使おう!
すごいConstたのしく使おう!
Akihiro Nishimura
クロージャデザインパターン
クロージャデザインパターン
Moriharu Ohzu
PWNの超入門 大和セキュリティ神戸 2018-03-25
PWNの超入門 大和セキュリティ神戸 2018-03-25
Isaac Mathis
Visual C++コード分析を支えるSAL
Visual C++コード分析を支えるSAL
egtra
C++の話(本当にあった怖い話)
C++の話(本当にあった怖い話)
Yuki Tamura
「日本語LaTeX」が多すぎる件について
「日本語LaTeX」が多すぎる件について
Takayuki Yato
Effective Modern C++ 勉強会 Item26
Effective Modern C++ 勉強会 Item26
Akihiro Nishimura
LR parsing
LR parsing
ichikaz3
What's hot
(20)
Effective Modern C++勉強会#4 Item 17, 18資料
Effective Modern C++勉強会#4 Item 17, 18資料
Effective Modern C++ 勉強会#3 Item16
Effective Modern C++ 勉強会#3 Item16
Effective Modern C++ 勉強会#3 Item 15
Effective Modern C++ 勉強会#3 Item 15
Effective Modern C++ 勉強会#7 Item 27
Effective Modern C++ 勉強会#7 Item 27
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
templateとautoの型推論
templateとautoの型推論
クソザコ鳥頭が非順序連想コンテナに入門してみた
クソザコ鳥頭が非順序連想コンテナに入門してみた
unique_ptrにポインタ以外のものを持たせるとき
unique_ptrにポインタ以外のものを持たせるとき
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30
[C++ Korea] Effective Modern C++ Study, Item 27, 29 - 30
Visual C++で使えるC++11
Visual C++で使えるC++11
C++ ポインタ ブートキャンプ
C++ ポインタ ブートキャンプ
良い?悪い?コードコメントの書き方
良い?悪い?コードコメントの書き方
すごいConstたのしく使おう!
すごいConstたのしく使おう!
クロージャデザインパターン
クロージャデザインパターン
PWNの超入門 大和セキュリティ神戸 2018-03-25
PWNの超入門 大和セキュリティ神戸 2018-03-25
Visual C++コード分析を支えるSAL
Visual C++コード分析を支えるSAL
C++の話(本当にあった怖い話)
C++の話(本当にあった怖い話)
「日本語LaTeX」が多すぎる件について
「日本語LaTeX」が多すぎる件について
Effective Modern C++ 勉強会 Item26
Effective Modern C++ 勉強会 Item26
LR parsing
LR parsing
Similar to Emcpp item31
C++ lecture-1
C++ lecture-1
sunaemon
Boost Tour 1.50.0 All
Boost Tour 1.50.0 All
Akira Takahashi
Boost tour 1_40_0
Boost tour 1_40_0
Akira Takahashi
C++ lecture-0
C++ lecture-0
sunaemon
boost tour 1.48.0 all
boost tour 1.48.0 all
Akira Takahashi
C++0x concept
C++0x concept
Akira Takahashi
Lambda in template_final
Lambda in template_final
Cryolite
C++0x in programming competition
C++0x in programming competition
yak1ex
C++0x総復習
C++0x総復習
道化師 堂華
C++ tips 3 カンマ演算子編
C++ tips 3 カンマ演算子編
道化師 堂華
C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミング
Kohsuke Yuasa
Cython intro prelerease
Cython intro prelerease
Shiqiao Du
Brief introduction of Boost.ICL
Brief introduction of Boost.ICL
yak1ex
T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門
伸男 伊藤
Wrapping a C++ library with Cython
Wrapping a C++ library with Cython
fuzzysphere
Boost.Flyweight
Boost.Flyweight
gintenlabo
NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門
Shiqiao Du
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
Preferred Networks
“Symbolic bounds analysis of pointers, array indices, and accessed memory reg...
“Symbolic bounds analysis of pointers, array indices, and accessed memory reg...
Masahiro Sakai
Introduction to cython
Introduction to cython
Atsuo Ishimoto
Similar to Emcpp item31
(20)
C++ lecture-1
C++ lecture-1
Boost Tour 1.50.0 All
Boost Tour 1.50.0 All
Boost tour 1_40_0
Boost tour 1_40_0
C++ lecture-0
C++ lecture-0
boost tour 1.48.0 all
boost tour 1.48.0 all
C++0x concept
C++0x concept
Lambda in template_final
Lambda in template_final
C++0x in programming competition
C++0x in programming competition
C++0x総復習
C++0x総復習
C++ tips 3 カンマ演算子編
C++ tips 3 カンマ演算子編
C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミング
Cython intro prelerease
Cython intro prelerease
Brief introduction of Boost.ICL
Brief introduction of Boost.ICL
T69 c++cli ネイティブライブラリラッピング入門
T69 c++cli ネイティブライブラリラッピング入門
Wrapping a C++ library with Cython
Wrapping a C++ library with Cython
Boost.Flyweight
Boost.Flyweight
NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
“Symbolic bounds analysis of pointers, array indices, and accessed memory reg...
“Symbolic bounds analysis of pointers, array indices, and accessed memory reg...
Introduction to cython
Introduction to cython
Emcpp item31
1.
ITEM 31. AVOID
DEFAULT CAPTURE MODES. MITSUTAKA TAKEDA MITSUTAKA.TAKEDA@GMAIL.COM
2.
TABLE OF CONTENTS 自己紹介 Chapter
6. Lambda Expressions Item 31: Avoid default capture modes default by-reference capture default by-value capture Review おまけ
3.
自己紹介 C++プログラマ@株式会社Skeed ネットワーク系のライブラリ開発(C++11)
4.
5.
CHAPTER 6. LAMBDA
EXPRESSIONS
6.
LAMBDA No new expressive
power, but a game changer. 関数オブジェクト(ファンクタ*1)をインラインで定義できる。 *1 関数型プログラミング界隈から怒られるのでファンクタと呼ぶ のはやめましょう
7.
用途 std::unique_ptr、 std::shared_ptr のデリータ STL
algorithms コール・バックの定義 API変更
8.
用語 lambda expression: ソース・コード中に記載されている式。 image
from closure class & object: lambda expressionから生成される無 http://www.nullptr.me/2011/10/12/c11- lambda-having-fun-with-brackets/
9.
名関数オブジェクト・クラスとそのインスタンス。 CAPTURE MODE default
explicit by-value [=] [var] by-reference [&] [&var] void f() { int x = 0, y = 0; auto default_by_value = [=] {/* xとyのコピーをキャプチャ */}; auto default_by_reference = [&] {/* xとyへの参照をキャプチャ */}; auto explict_by_value = [x] {/* xのコピーをキャプチャ */}; auto explict_by_reference = [&x]{/* xへの参照をキャプチャ */}; }
10.
ITEM 31: AVOID
DEFAULT CAPTURE MODES 2 default capture modes. by-reference by-value どちらのdefault capture modeも、キャプチャしたオブジェクトが ダングリング参照になる可能性があるので使用しないほうが良 い。
11.
DEFAULT BY-REFERENCE CAPTURE using
FilterContainer = std::vector<std::function<bool(int)> >; FilterContainer filters; int computeSomveValue1() { return 42; } int computeSomveValue2() { return 7; } int computeDivisor(int x, int y) { return 7; } void addDivisorFilter() { auto calc1 = computeSomveValue1(); auto calc2 = computeSomveValue2(); auto divisor = computeDivisor(calc1, calc2); // ローカル変数。 filters.emplace_back( [&] // default by-reference capture。 (int value){ // divisor↓はローカル変数divisor↑への参照。 return (value % divisor) == 0; } ); // addDivisorFilterが終了するとローカル変数divisorは消滅。 // キャプチャしているdivisorはダングリング参照。 } int main() { addDivisorFilter(); for(auto& f : filters) { // fを使用すると未定義動作。 } }
12.
EXPLICIT BY-REFERENCE CAPTURE 明示的にキャプチャしてもダングリング参照は回避できない。 明示的にキャプチャすることでキャプチャされている変数 (divisor)の寿命に注意できるのでbetter。
closureの寿命よりキ ャプチャされているオブジェクトの寿命が長くなければいけない。 void addDivisorFilter() { auto calc1 = computeSomveValue1(); auto calc2 = computeSomveValue2(); auto divisor = computeDivisor(calc1, calc2); // ローカル変数。 filters.emplace_back( [&divisor] // <- 明示的にdivisorを参照でキャプチャ。 (int value){ return (value % divisor) == 0; } ); // addDivisorFilterが終了するとローカル変数divisorは消滅。 // キャプチャdivisorはダングリング参照。 }
13.
CLOSURE FOR SHORT
LIFETIME STLアルゴリズムの引数として利用するときなど、closureの寿命 が短かい時は、 default by-reference captureは安全? ダングリング参照は起きない。しかし、lambdaがダングリング参 照を起すコンテキスト(addDivisorFilter)にコピペされてしまう危 険性が有る。 template <typename C> void workWithContainer(const C& container) { auto calc1 = computeSomveValue1(); auto calc2 = computeSomveValue2(); auto divisor = computeDivisor(calc1, calc2); using ContElemT = typename C::value_type;// C++14では不要。 using std::begin; using std::end; if(std::all_of(begin(container), end(container), [&] // default by-value captureしているがローカル変数divisorは、クロージャよ り寿命が長いので大丈夫。 (const ContElemT& value){ // C++14 ではGeneric Lambda (const auto& value) で 書けるよ。 return (value % divisor) == 0; })) { /*...*/ } }
14.
DEFAULT BY-VALUE CAPTURE default
by-reference captureはダングリング参照が問題。 default by-value captureなら問題が無い? void addDivisorFilter() { auto calc1 = computeSomveValue1(); auto calc2 = computeSomveValue2(); auto divisor = computeDivisor(calc1, calc2); // ローカル変数。 filters.emplace_back( [=] // default by-value capture (int value){ // divisorはローカル変数のコピーなのでダングリング参照は起きない。 return (value % divisor) == 0; } ); }
15.
PROBLEM WITH BY-VALUE
CAPTURE 1 addDivisorFilterの例ではダングリング参照の問題は解消す る。しかし、ポインタをby-value captureすると、 pointerが closureの外から削除された場合、ダングリング参照の問題が起 きる。 void addDivisorFilter() { auto calc1 = computeSomveValue1(); auto calc2 = computeSomveValue2(); int* divisor = new int(computeDivisor(calc1, calc2)); // intへのポインタ。 filters.emplace_back( [=] // <- default by-value capture (int value){ // divisorはポインタのコピー。 return (value % (*divisor)) == 0; } ); delete divisor; // divisorが指すオブジェクトは消滅してダングリング。 }
16.
PROBLEM WITH BY-VALUE
CAPTURE 2 スマート・ポインタを使えばダングリング問題は起きない。万事 解決? void addDivisorFilter() { auto calc1 = computeSomveValue1(); auto calc2 = computeSomveValue2(); auto divisor = std::make_shared<const int>(computeDivisor(calc1, calc2)); // intへ のshared_ptr。 filters.emplace_back( [=] // <- default by-value capture (int value){ // closureが生きているかぎり参照カウントは0にならないのでダングリ ングにならない。 return (value % (*divisor)) == 0; } ); }
17.
CAPTURE OF MEMBER
VARIABLE lambdaが定義されているスコープで見ることができるnon-static ローカル変数と関数パラメータのみcaptureできる。 メンバ変数はどのようにキャプチャされるか。 std::vector<std::function<bool(int)> > filters; class Widget { public: void addFilter() const { filters.emplace_back( [=] // default by-value capture。 // default([=])の代りにexplicit by-value capture([divisor]) // しようとするとコンパイル・エラー。 (int value) { return (value % divisor) == 0; // divisorはメンバ変数のキャプチャ。 }); } private: int divisor; };
18.
CAPTURE OF MEMBER
VARIABLE 2 キャプチャされるのはメンバ変数ではなくて、thisポインタ。概念 的には以下のコードと等価。 std::vector<std::function<bool(int)> > filters; class Widget { public: void addFilter() const { auto currentObjectPtr = this; filters.emplace_back( [currentObjectPtr] // thisポインタをキャプチャ。 (int value) { return (value % currentObjectPtr->divisor) == 0; }); } private: int divisor; }; ところで、thisポインタを明示的にキャプチャするにはcapture listにthisと書けば良い。
19.
PROBLEM WITH CAPTURING
MEMBER VARIABLES thisポインタは非スマート・ポインタ。closureがthisの指すオブジ ェクトより長く生存するとダングリング参照。 ModernなC++スタ イル(スマート・ポインタ)でもダングリング参照は回避できない。 std::vector<std::function<bool(int)> > filters; class Widget { public: void addFilter() const { filters.emplace_back( [=] (int value) { return (value % divisor) == 0; }); } private: int divisor; }; int main(int argc, char *argv[]) { { auto w = std::make_unique<Widget>(); w->addFilter(); } // wが指すオブジェクトは破棄されfiltersのなかにあるdivisorはダングリング。 return 0; }
20.
HOW TO AVOID
A DANGLING REFERENCE 今回のようなケースでは、メンバ変数をローカル変数にコピーす る(C++11)、または、generalized lambda capture(C++14 & Item 32)で ダングリング参照を回避できる。 class Widget { public: void addFilter_CPP_11_Style() const { auto divisorCopy = divisor; // ローカル変数にメンバ変数をコピー。 filters.emplace_back( [divisorCopy] // ローカル変数のコピーをexplict by-value capture。 (int value) { return (value % divisorCopy) == 0; }); } void addFilter_CPP_14_Style() const { filters.emplace_back( [divisor = this->divisor] // メンバ変数をgeneralized lambda captureでコピー する。 (int value) { return (value % divisor) == 0; }); } private: int divisor; };
21.
ADDITIONAL DRAWBACKS OF
DEFAULT BY-VALUE CAPTURE default by-value captureは、オブジェクトを"コピーしている"の でclosureは外部環境から独立していると錯覚させやすい。 しか し実際にはstaticストレージのオブジェクトにも依存している。 by-valueキャプチャしているのにclosureは値のセマンティックス ではなく参照のセマンティックスで動作する。 void addDivisorFilter() { static auto calc1 = computeSomveValue1(); static auto calc2 = computeSomveValue2(); static auto divisor = computeDivisor(calc1, calc2); // intへのshared_ptr。 filters.emplace_back( [=] // 何もキャプチャしていない (int value){ // divisorはキャプチャではなく上記のstatic変数そのもの。 return (value % divisor) == 0; } ); ++divisor; // staticオブジェクトへの変更は↑のclosureへも影響する。 }
22.
REVIEW default captureは以下の理由から避けよう。 default by-reference
captureはダングリング参照になる危険 性 default by-value captureはダングリング参照になる危険性 (特にthisポインタを通じて) & lambdaが外部環境から独立し ていると錯覚
23.
おまけ IIFE IN C++
For Performance and Safety@C++ Now 2015 Imediately Invoked Function Expression Lambda expressionを定義と同時に呼出す。
24.
IMEDIATELY INVOKED FUNCTION
EXPRESSION 条件によって初期化が異なる。 bool condition = ...; auto size = 0; // 任意の値で初期化、または、未初期化。 if(condition){ size = 1; } else { size = 2; } // これ以降のコードではsizeはread only。sizeはconstであるべき。
25.
IMEDIATELY INVOKED FUNCTION
EXPRESSION これならコピペされても大丈夫? bool condition = ...; const auto size = [&]{// default by-reference capture. if(condition){ return 1; } else { return 2; } }(); // lambda expressionを定義と同時に呼出す。
Download now