C++ tips 3 カンマ演算子編
Upcoming SlideShare
Loading in...5
×
 

C++ tips 3 カンマ演算子編

on

  • 3,510 views

主に cppll ML でご紹介してきた tips をC++の仕様をより掘り下げた形でまとめ直してみました。

主に cppll ML でご紹介してきた tips をC++の仕様をより掘り下げた形でまとめ直してみました。
今回はカンマ演算子にフォーカスした内容です。

Statistics

Views

Total Views
3,510
Views on SlideShare
3,498
Embed Views
12

Actions

Likes
3
Downloads
16
Comments
0

2 Embeds 12

https://twitter.com 10
http://us-w1.rockmelt.com 2

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

C++ tips 3 カンマ演算子編 C++ tips 3 カンマ演算子編 Presentation Transcript

  • Boost.勉強会 #8 大阪 ( 2012-02-11 )C++ TIPS 3 カンマ演算子編
  • 概要 主に cppll ML でご紹介してきた tips をC++ の仕様をより掘り下げた形でまとめ直し てみました。 今回はカンマ演算子にフォーカスした内 容です。 C++ Tips Boost.勉強会 #8 大阪 2
  • C++ Tipsカンマ演算子 View slide
  • カンマ演算子ってなに? セミコロン(;)が文の区切りとして使える ように、カンマ(,)が文節として使えます。  日本語文章で例えると「;」が「 。 」に対応 するのに対して「,」は「、」に対応してい ます。 この用法で使われるカンマはカンマ演算 子と呼ばれます。 C++ Tips Boost.勉強会 #8 大阪 4 View slide
  • カンマ演算子ってなに? 関数呼び出しのカンマや初期化ブロック 内のカンマ区切りはカンマ演算子ではあ りません。 関数呼び出しのカンマ区切りと違って評 価順は左側の項目が先と決まってます。 カンマ演算子はもっとも優先順位の低い 演算子となります。 C++ Tips Boost.勉強会 #8 大阪 5
  • カンマ演算子の動きint a() { puts("a"); return 1; } ■実行結果int b() { puts("b"); return 2; } aint c() { puts("c"); return 4; } bvoid func() { c int x = (a(),b(),c()); 4 printf("%dn",x);}  左から順に評価され最も右側の値が式の評価値となり ます。( オーバーロードされていない場合 ) C++ Tips Boost.勉強会 #8 大阪 6
  • 余談というか落とし穴int x = (a(),b(),c());…のつもりで…int x = a(),b(),c();…と書くとカンマ演算子ではなく、宣言のカンマ区切りだとコンパイラに解釈され…int x = a(); // a() を実行して x に初期値にする。int b(); // 戻り型が int の関数 b() の宣言。int c(); // 戻り型が int の関数 c() の宣言。…の意味になってしまいます。 C++ Tips Boost.勉強会 #8 大阪 7
  • 使用例:ifif (a(),b(),c()) // c()結果で分岐{ ... }elseif (d(),e(),f()) // f()結果で分岐{ ... }elseif (g(),h(),i()) // i()結果で分岐{ ... }else{ ... } C++ Tips Boost.勉強会 #8 大阪 8
  • 使用例:ifif (x=a(),b(x),c()) // c()の結果で分岐{ ... }elseif (d(),e=x+i,f(e)) // f(e)の結果で分岐{ ... }elseif (g(),i=h(),i++) // i++の結果で分岐{ ... }else{ ... } C++ Tips Boost.勉強会 #8 大阪 9
  • 使用例:switchif (a(),b(),c()) // c()の結果で分岐{ ... }elseswitch(d(),e(),f()) // f()の結果で分岐{case 0: ...default: ...} C++ Tips Boost.勉強会 #8 大阪 10
  • 使用例:while,do/whilewhile(a(),b(),c()) // c()の結果で分岐{ ... }do{ ... }while(d(),e(),f()); // f()の結果で分岐 C++ Tips Boost.勉強会 #8 大阪 11
  • 使用例:forfor(int i=0,j=0; a(i),b(j); c(&i),d(&j)){ ... } // b()の結果で分岐※最初のカンマはカンマ演算子ではなく宣言のカンマ区切りとなります。 C++ Tips Boost.勉強会 #8 大阪 12
  • 使用例:引数x((a(),b(),c()), (d(),e(),f()), (g(),h(),i())); この場合、( )各グループ内では… a()→b()→c()、 d()→e()→f()、 g()→h()→i() …の順で実行されます が、abc、def、ghiの各グループの実行される順番は処理 系依存となる為、処理系によって abc→def→ghi だった り ghi→def→abc だったりします。  この順番は通常、関数の引数がどのような順番でスタック に積まれるか依存します。 C++ Tips Boost.勉強会 #8 大阪 13
  • 使用例:|| と && 組み合わせて( (a(),b(),c()) || (d(),e(),f()) // c()がfalseの場合に実行) && (g(),h(),i()); // c()||f()がtrueの場合に実行 C++ Tips Boost.勉強会 #8 大阪 14
  • \ ヒャッハー! /int x = ( (++i,y=a(),b(y),c(i)) || (++i,y=d(),e(i),z=f(y,i) ? g(): h())) && ( (++i,y=a(),b(y),c(i)) || (++i,y=d(),e(i),y<=f(y,i))); C++ Tips Boost.勉強会 #8 大阪 15
  • スタック領域の圧迫について カンマ演算子を多用して頑張ると一文で結構な量のコードが書けてしまうのですが、あんまり調子扱いてると一時変数の量が膨大になってスタック領域を圧迫し状況によってはスタックオーバーフローを招くことにもなりかねない観点からもほどほどに。 C++ Tips Boost.勉強会 #8 大阪 16
  • インラインロック カンマ演算子は左側の項目から評価されるという事と、一時オブジェクトの寿命は文の終了時までという事を利用し、コンストラクタでロック、デスクトラクタでアンロックを行うクラスを用意しておけばインラインでの手軽なロック/アンロックができます。 C++ Tips Boost.勉強会 #8 大阪 17
  • インラインロックauto_lock(),func(); ■実行される順番 1.auto_lock::auto_lock() 2.func() 3.auto_lock::~auto_lock() C++ Tips Boost.勉強会 #8 大阪 18
  • インラインロックif (auto_lock(),func()) { func2(); } ■実行される順番 1.auto_lock::auto_lock() 2.func() 3.auto_lock::~auto_lock() 4.func2() →func()がtrueの場合にのみ実行される。 C++ Tips Boost.勉強会 #8 大阪 19
  • オーバーロード カンマ演算子はオーバーロードしてその挙動をユーザー定義することも可能です。 inline hoge operator,(hoge a, hoge b) { return a; // b の代わりに a を返す。 } C++ Tips Boost.勉強会 #8 大阪 20
  • 初期化リスト代わり カンマ演算子のオーバーロードを頑張ればC++11の初期化リストの代わりになるような類いのもの実装可能です。 C++ Tips Boost.勉強会 #8 大阪 21
  • オーバーロード 注意点 その他演算子オーバーロード違い、カンマ演算子の オーバーロードは見た目からはオーバーロードされて いることが予測し辛い為、容易くメンテナンス性の悪 いコードになってしまいますので、乱用は厳禁です。 C++03時代であればまだ初期化リスト代わりの用途とし てカンマ演算子のオーバーロードが有効なシーンも あったもののC++11では素直に初期化リストを使ったほ うがいいです。 さらにC++03でも昔のコンパイラではカンマ演算子の オーバーロードまわりはコンパイラの挙動がバギーで 使い物にならなかったり・・・ C++ Tips Boost.勉強会 #8 大阪 22
  • C++ Tips質疑応答
  • C++ Tipsご清聴ありがとうございました。