Submit Search
Upload
Emcpp item31
•
3 likes
•
10,915 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
Emcpp0506
Emcpp0506
Takatoshi Kondo
effective modern c++ chapeter36
effective modern c++ chapeter36
Tatsuki SHIMIZU
Effective modern c++ 8
Effective modern c++ 8
uchan_nos
Modern c++ (C++ 11/14)
Modern c++ (C++ 11/14)
Geeks Anonymes
Effective Modern C++ 勉強会#1 Item3,4
Effective Modern C++ 勉強会#1 Item3,4
Takashi Hoshino
Effective Modern C++勉強会#4 Item 17, 18資料
Effective Modern C++勉強会#4 Item 17, 18資料
Ryo Igarashi
Effective modern c++ 5
Effective modern c++ 5
uchan_nos
Recommended
emc++ chapter32
emc++ chapter32
Tatsuki SHIMIZU
Emcpp0506
Emcpp0506
Takatoshi Kondo
effective modern c++ chapeter36
effective modern c++ chapeter36
Tatsuki SHIMIZU
Effective modern c++ 8
Effective modern c++ 8
uchan_nos
Modern c++ (C++ 11/14)
Modern c++ (C++ 11/14)
Geeks Anonymes
Effective Modern C++ 勉強会#1 Item3,4
Effective Modern C++ 勉強会#1 Item3,4
Takashi Hoshino
Effective Modern C++勉強会#4 Item 17, 18資料
Effective Modern C++勉強会#4 Item 17, 18資料
Ryo Igarashi
Effective modern c++ 5
Effective modern c++ 5
uchan_nos
Effective Modern C++ 勉強会#3 Item 15
Effective Modern C++ 勉強会#3 Item 15
Mitsuru Kariya
Effective Modern C++ Item 9 and 10
Effective Modern C++ Item 9 and 10
uchan_nos
Advanced C - Part 1
Advanced C - Part 1
Emertxe Information Technologies Pvt Ltd
self_refrential_structures.pptx
self_refrential_structures.pptx
AshishNayyar12
C programming language tutorial
C programming language tutorial
javaTpoint s
Embedded C - Lecture 4
Embedded C - Lecture 4
Mohamed Abdallah
templateとautoの型推論
templateとautoの型推論
MITSUNARI Shigeo
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
Ryo Suzuki
C++ 11 Features
C++ 11 Features
Jan Rüegg
リテラル文字列型までの道
リテラル文字列型までの道
Satoshi Sato
Threads and Callbacks for Embedded Python
Threads and Callbacks for Embedded Python
Yi-Lung Tsai
C++14 - Modern Programming for Demanding Times
C++14 - Modern Programming for Demanding Times
Carlos Miguel Ferreira
COMPILATION PROCESS IN C.pptx
COMPILATION PROCESS IN C.pptx
LECO9
Effective Modern C++ 勉強会#3 Item16
Effective Modern C++ 勉強会#3 Item16
Mitsuru Kariya
Emcjp item21
Emcjp item21
MITSUNARI Shigeo
Git, CMake, Conan - How to ship and reuse our C++ projects?
Git, CMake, Conan - How to ship and reuse our C++ projects?
Mateusz Pusz
Embedded C
Embedded C
Emertxe Information Technologies Pvt Ltd
Effective Modern C++ 勉強会#7 Item 27
Effective Modern C++ 勉強会#7 Item 27
Mitsuru Kariya
COM1407: Working with Pointers
COM1407: Working with Pointers
Hemantha Kulathilake
C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会
Akihiko Matuura
C++ lecture-1
C++ lecture-1
sunaemon
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
kikairoya
More Related Content
What's hot
Effective Modern C++ 勉強会#3 Item 15
Effective Modern C++ 勉強会#3 Item 15
Mitsuru Kariya
Effective Modern C++ Item 9 and 10
Effective Modern C++ Item 9 and 10
uchan_nos
Advanced C - Part 1
Advanced C - Part 1
Emertxe Information Technologies Pvt Ltd
self_refrential_structures.pptx
self_refrential_structures.pptx
AshishNayyar12
C programming language tutorial
C programming language tutorial
javaTpoint s
Embedded C - Lecture 4
Embedded C - Lecture 4
Mohamed Abdallah
templateとautoの型推論
templateとautoの型推論
MITSUNARI Shigeo
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
Ryo Suzuki
C++ 11 Features
C++ 11 Features
Jan Rüegg
リテラル文字列型までの道
リテラル文字列型までの道
Satoshi Sato
Threads and Callbacks for Embedded Python
Threads and Callbacks for Embedded Python
Yi-Lung Tsai
C++14 - Modern Programming for Demanding Times
C++14 - Modern Programming for Demanding Times
Carlos Miguel Ferreira
COMPILATION PROCESS IN C.pptx
COMPILATION PROCESS IN C.pptx
LECO9
Effective Modern C++ 勉強会#3 Item16
Effective Modern C++ 勉強会#3 Item16
Mitsuru Kariya
Emcjp item21
Emcjp item21
MITSUNARI Shigeo
Git, CMake, Conan - How to ship and reuse our C++ projects?
Git, CMake, Conan - How to ship and reuse our C++ projects?
Mateusz Pusz
Embedded C
Embedded C
Emertxe Information Technologies Pvt Ltd
Effective Modern C++ 勉強会#7 Item 27
Effective Modern C++ 勉強会#7 Item 27
Mitsuru Kariya
COM1407: Working with Pointers
COM1407: Working with Pointers
Hemantha Kulathilake
C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会
Akihiko Matuura
What's hot
(20)
Effective Modern C++ 勉強会#3 Item 15
Effective Modern C++ 勉強会#3 Item 15
Effective Modern C++ Item 9 and 10
Effective Modern C++ Item 9 and 10
Advanced C - Part 1
Advanced C - Part 1
self_refrential_structures.pptx
self_refrential_structures.pptx
C programming language tutorial
C programming language tutorial
Embedded C - Lecture 4
Embedded C - Lecture 4
templateとautoの型推論
templateとautoの型推論
ゲーム開発者のための C++11/C++14
ゲーム開発者のための C++11/C++14
C++ 11 Features
C++ 11 Features
リテラル文字列型までの道
リテラル文字列型までの道
Threads and Callbacks for Embedded Python
Threads and Callbacks for Embedded Python
C++14 - Modern Programming for Demanding Times
C++14 - Modern Programming for Demanding Times
COMPILATION PROCESS IN C.pptx
COMPILATION PROCESS IN C.pptx
Effective Modern C++ 勉強会#3 Item16
Effective Modern C++ 勉強会#3 Item16
Emcjp item21
Emcjp item21
Git, CMake, Conan - How to ship and reuse our C++ projects?
Git, CMake, Conan - How to ship and reuse our C++ projects?
Embedded C
Embedded C
Effective Modern C++ 勉強会#7 Item 27
Effective Modern C++ 勉強会#7 Item 27
COM1407: Working with Pointers
COM1407: Working with Pointers
C++ Template Meta Programming の紹介@社内勉強会
C++ Template Meta Programming の紹介@社内勉強会
Similar to Emcpp item31
C++ lecture-1
C++ lecture-1
sunaemon
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
kikairoya
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
Visual C++コード分析を支えるSAL
Visual C++コード分析を支えるSAL
egtra
Visual C++で使えるC++11
Visual C++で使えるC++11
nekko1119
NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門
Shiqiao Du
Similar to Emcpp item31
(20)
C++ lecture-1
C++ lecture-1
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
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
Visual C++コード分析を支えるSAL
Visual C++コード分析を支えるSAL
Visual C++で使えるC++11
Visual C++で使えるC++11
NumPyが物足りない人へのCython入門
NumPyが物足りない人への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