C++

void (*(*f[])())()の解読のしかた

C言語の演算子の優先順位はけっこう複雑な方だとおもう。

宣言の読み方が難しいのは宣言に出てくる演算子の優先度がわかりにくいのもあるが、ポインタのデリファレンス演算子 * が前置演算子になっているのが原因だとおもう。他の演算子 関数呼び出しの ()・配列アクセスの [] は後置演算子で、ポインタの * よりも優先度が高いのでポインタ演算子を先に効かせたい場合に括弧が必要になって見た目が複雑になる。

void (*(*f[])())() の読み方

f は変数
f[] fは配列
*f[] 配列の要素はポインタ
(*f[])() ポインタは関数を指している
*(*f[])() 関数はポインタを返す
(*(*f[])())() 返ってきたポインタは関数を指している
void (*(*f[])())() 関数の戻り値はvoid

仮にポインタデリファレンスが前置 の * ではなくて後置の @ だとしたらどうなるか。

void (*(*f[])())()

void f[]@()@()

と書けて、最初の型以外は左から右に直線的に読むだけで済む。

IMG_20180606_001314

Statements and Declarations in Expressions

gcc/clangでは拡張で式文がつかえるが、これはC++11で入ったlambdaで同じことができるし、オブジェクトとして扱えるとかキャプチャがあるとかでむしろ高機能なのだが、デバッグで一時的に文字列を生成したいときにalloca()で領域確保したいときにlambdaは使えなかった。

#include <iostream>
#include <string.h>
#include <stdlib.h>
int
main()
{
    char *p1 = ({ char* p = (char*)alloca(100); strcpy(p, "aaa"); p; });
    char *p2 = ([]() { char* p = (char*)alloca(100); strcpy(p, "bbb"); return p; })();
    std::cout << p1 << std::endl;
    std::cout << p2 << std::endl;
}
% clang++ -std=gnu++11 foo.cc
% ./a.out
aaa

%

koie

いってきた: ドワンゴC++勉強会 #1

あわててでかける。電車の乗り換え待ち時間に菓子パンを流し込む。

image

丸の内線の銀座駅で降りて地下道で東銀座へ。時間ぎりぎりで会場に到着。

_1200362_1200351

constexpr関数処理はコンパイル時処理。これはいい。実行時が霞んで見える。CPUの嬌声が聞こえてきそうだ / ボレロ村上 @bolero_MURAKAMI

  • 資料: http://www.slideshare.net/GenyaMurakami/onstexprcpu
  • ふだんは岡山で陶芸家で縄文式土器をつくっている。
  • constexpr: C++11で導入→C++14で大幅緩和
    • constは修飾子、consteprは宣言での指定子
  • constexpr導入の動機
    • コンパイル時評価 (C++03ではnumeric_limits::max()がコンパイル時にしか呼べなかった)
    • テンプレートメタプログラミングの置き換え
  • C++11: ローカル変数だめ、副作用だめ(iostreamとか)、ループ/ifはだめ(?:と再帰で書く)、returnは1箇所だけ。
    • 再帰は最初は許可されない予定だった。再帰がないとTMP(template meta programming)をおきかえられない。
  • C++14: 緩和されてgoto以外の文をいくらでも書けるように。
  • C++11でfind()を実装しようとすると分割統治(log N)にしないとネストの制限にひっかかってしまう。線形サーチだと(N)。
  • C++14のfind()/merge()ならconstexprをつけるだけ。merge()はoutputiteratorをつかうので。
  • C++14: IO, new, try-catch (throwは書ける), RAII, lambda expr, グローバル変数の参照(参照しなければよい).
  • C++11のconstexprはinlineの最適化ににたやりかたで置換してた。
  • C++14のconstexprは抽象マシンで定義。
  • gccはmemoizeを載せてるので速いが、32x32 pixelのレイトレーシング 8GBくらい喰う。
  • boostの特徴: ダックタイピング(generic programming)、自由関数で実現(cf std::string)、疎結合、機能分割がしっかり。
  • templateをつかうのがC++らしさに。
  • constexprをつかうようにするとC++らしくなる(らしい)
  • 仮想関数をconstexprにおきかえるには?→型パラメータをつかう。
  • range: begin,endイテレータの組
  • range | adaptor がrangeをかえす。rangeアダプタは通常副作用を持たない。
  • コンテナよりもrangeをつかおう。ForwardIterator,InputIteratorをつかおう。型制約をつかおう。
  • メンバ関数をつかわないように。
  • sproutの例
    • Sprout.Darkroom: タプルの組み合わせで表現。配置物は関数オブジェクトで表現。
      • 8Kix8Ki pixのレイトレーシングで160時間。いちどにはできない(メモリが足りない)ので、4x4で計算したのを結合する。
    • Sprout.Weed: パーサコンビネータ
      • expression template(ET)をつかっている。ETは一時変数の使用を抑制するために発明された(行列とか)。boost.sprit。
    • Sprout.Compst: コンパイル時波形処理
      • 基本波形はRangeとして表現されている。
      • シンセサイザーエフェクトはRangeアダプター。エフェクトを重ねると型がたいへんなことになる。
  • C++14ドラフト: std::array::operator[]の非const版はまだconsteprされていない。
    • 標準ライブラリに独自拡張をすると規格違反になるので、実装実績を積むのがむつかしくなる。
  • C++1x → C++14, C++1z → C++17?

[2014-06-28 15:06]

  • Q: サイズ可変なコンテナがあつかえないのは困る。
  • A: 実用的につかえるようにするにはnewが必要で、それはGCがあれば可能らしい?
  • Q: conextexprで書くと実行時の性能はどうか?
  • A: ケースバイケースだが、find()などは変らないパフォーマンス、sort()は動的なメモリを使えないのでちょと落る。コンパイル時と実行時でコードを変えるのは入らないっぽい(is_constexpr)。

[2014-06-28 15:12]

トイレ+休憩

缶コーヒー80円ごくごく。

[2014-06-28 15:20]

Define and Expresssion of CPP macro / でちまる @decimalbloat

  • 資料: http://www.slideshare.net/digitalghost/define-andexpansionofcppmacro
  • Cプリプロセッサメタプログラミング
    • sed/awkとかわらない字句レベルC++のコードを生成する。
  • 構文を理解するCPPも提案はされた。10年単位で待てば。
  • 暴力で解決。
  • BOOST_PP_ と名前がぶつかるのは、当たり屋。
  • PHP/perlでコードジェネレートすればいい。
  • 評価順序がCとCPPで大きく違う。外側から評価する; 外側を置換→連結→置換→元の場所に挿入→最初にもどる

>}}

#define CAT(a,b) CAt1(a,b)

#define CAT1(a,b) a##b

CAT(a, CAT(b,c))

=> ABC

||<

  • 基本的に数値やboolをあつかうにはdefineを並べるしかない。
  • データ構造: シーケンス:(a)(b)(c)かタプル(a,b,c)か、よく使うのはこの二種類。
  • シーケンスは長さがかえられる、タプルは固定長(variadic macroがはいったので、どんな長さでも化).

[2014-06-28 16:06]

  • Q: CPPとおしたあとのコードをみやすくするには?
  • A: 手で改行を入れる。boost wave? pragma でデバッグ出力できる? gccとwaveで展開規則がちょっとちがってるので使えないかも?
  • Q: SCOPE_EXITの名前をユニークにするには?
  • A: __LINE__をつかっている。乱数を生成するマクロとかVCには自動インクリメントされるマクロがある?

[2014-06-28 16:09]

[2014-06-28 16:16]

C++の歴史 / 江添 @EzoeRyou

  • Cpre → C with Clsses: まだプリプロセッサレベル。線形探索より難しいアルゴリズムなしに実装できるべき。
  • メタプログラミングの初期に発見された技法はC++の新規格の叩き台として有効。
  • 過去: ANSI下院 ISO上院: ANSIがCDをだしてISOがNBを出してのループ
  • 昔は非公開、今はC++DraftはgithubにTeX。
  • C++98は新技術においつくために一旦出した。
  • C++03はバグフィックス版
  • C++l1はコンセプト機能を取り除くために1年半遅れた。
  • C++1yはC++11のマイナーアップデート (たぶんC++14) Clangは実装済。
  • C++17 (C++1z) メジャーアップデート。ドラフトもまだまだ。
  • EC++: 言語が分断するよりも標準化委員会に合流。Performance TRとしてまとめられる。
    • C++コンパイラーを1企業で開発できるような規模ではなくなった。(MS社くらい?)
  • ITSCJ(情報規格調査会)に金がない。ソフトウェアでのISOのブランドが低下。コミュニティ主導になってきた。
    • ISOはアメリカの独走に対抗するためにヨーロッパがつくった政治組織。
    • 個人メンバーやメールメンバーは2015/03でなくなってアドバイザーになる。
  • ここ半年は政治をやってた(現在進行形)

[2014-06-28 16:54]

  • Q: 今の組織を解体する?
  • A: たぶんむり。権利は手放さない。

[2014-06-28 16:55]

[2014-06-28 17:00]

templateで依存型 / 南山まさかず @minamiyama1994

[2014-06-28 17:05]

[2014-06-28 17:08]

constexpr idioms / @fimbul11

[2014-06-28 17:20]

  • Q: クラステンプレートを多用するが?
  • A: 線形や素朴な線形再帰でも小さいときは動くし。Nが大きくなったときにコンパイルできるかどうかが問題。
  • Q: find()など分割統治でやるとイテレータの計算量が大きくなる。
  • A: C++14ならループがいいけど、型MAPだとこういう技法をつかわざるをえない。

[2014-06-28 17:23]

[2014-06-28 17:24]

Cocos2dx(Ver2)が闇な話 / ぽんこつ @karupanerura

[2014-06-28 17:34]

[2014-06-28 17:35]

C++初心者書がC++11でparserを書いてみた話 / @karupanerura

  • lisp のparserをかいてみた。
  • auto便利. templateで長くなっても安心。
  • shared_ptr便利.
  • range for便利. autoとくみあわせると便利l.
  • 「オブジェクト指向」で書いてたので「constexpr」で書き直す。

[2014-06-28 17:41]

  • Q: 相互includeを避けるには必要なところだけ抜いてヘッダにするとかすれば解決。

[2014-06-28 17:44]

[2014-06-28 17:45]

valgrindは実行時メモリチェッカー。これはいい。コンパイル時チェックは結局頼りにならない。メモリの悲鳴が聞こえてきそうだ / @tikal

  • http://www.slideshare.net/ledyba/cpp-36404945
  • valgrind(バルちゃん)
    • 10倍くらい遅い。x86のコードを内部コードにしてチェックコードいれてx86にJITで変換。
    • シングルトンやキャシュをつかっていると誤爆
    • ドライバーのコードで誤検出する

[2014-06-28 17:51]

cocos2dx ver2ダメダメネタが三連発で開場沸いた。

はらへったのでスニッカーズをくってから、時折小雨のふる天気だが、有楽町まで地上をあるいてぶらぶらと帰る。

image_1200371

いってきた: 歌舞伎座.tech#2 11/14なのでC++11/14のお話

_1120958

東銀座に着いて地上に出て歌舞伎座をパチり。正面からだとどうみても歌舞伎座に入ってしまうようなので、また地下に降りてエレベーターを探すが、どのにエレベーターホールがあるのか、わかりにくいなぁ。

_1120959

7Fで乗り換えてオフィス用のエレベータにのりかえるところも、これまたわかりにくいなぁ。

_1120964

なんだかんだで10分前に入場。まだ席は半分くらいしか埋まってなかったが、最終的には席はほぼ埋まって、主催者の発表では出席率95%らしい。これってかなりの高出席率だよね。

電源タップをもっていったが床のコンセントに直刺ししたので使わず。でも前の席の人が困ってたので貸して、もってきたのが無駄にならなかった。

[2013-11-14 19:00]

あいさつ

_1120965

[2013-11-14 19:02]

C++11: variadic tempalteのご紹介 / επιστημη(エピスさん)_1120968

  • http://www.slideshare.net/ssuser1f23d9/episteme-variadic-template
  • 規格書(IS?)をみると割合は少なくてページ数は薄い。どうやってつかうんだろうかと悩むくらい。
  • 「...」は「だだだ」と読む。
  • variadic function, variadic macro, variadic template.
  • きもはparameter pack:
    • template parameter pack: 0個以上の型の並び。template struct Tuple {};
    • function paramter pack: 0個以上の値の並び。 template void f(Ts ...vs);
    • parameter packは型でも値もない。
    • sizeof... (Ts) とか sizeof... (vs) とかで個数がわかる。
    • ダダダを後ろにつけると展開される。
      • Ts... → T1,T2,…Tn
      • X::z → X::z, …
      • X → X
      • F(5,vs)... → F(5,v1),…
  • パターンマッチングで関数/クラスを書く。ベストマッチングで関数がえらばれる。
    • 再帰呼出ではなく、オーバーロードされた名前がいっしょの別の関数が呼ばれている。
  • 実演: http://youtu.be/B4RFqwg5oyA

[2013-11-14 19:22]

  • Q: 展開回数の上限
  • A: 最低も定義されてないが、推奨はある。

[2013-11-14 19:24]

休憩

[2013-11-14 19:31]

C++14の新機能 / 江添亮_1120971

  • 資料: http://ezoeryou.github.io/kabukiza-tech2-slide/index.html#/
  • まだドラフト
  • 二進数リテラル:
    • 0b10, 0B10。
    • 浮動小数点にはつかえない。
  • 数値区切り:
    • 1'0000 とか。0b10101010'10101010とか。2.14159'2 とか。
    • 一番先頭と最後以外ならどこにでも書ける。
    • 既存の文法に影響がなさそうなシングルクォートが選ばれた。強い圧力でnational body commentで入った。
    • アンダスコアだとユーザ定義リテラルと被る(ユーザ定義リテラルをなくせばいいんだけど)。空白文字も提案された。
  • 実行時サイズ配列:
    • 動的ストレージに配置されるのは許容される。
    • クラス内では使えない(GCCはできてしまうが)。clangは実装を拒否しているがlinuxではこれを多用している。
    • C99は可変長配列。C++14ではsizeofをサポートしない。dynarrayもC++14に入る。
  • [[deprecated]]:
    • getsとか。
    • 警告を出せる。プログラムの意味は変えない。
    • [[deprecated("messag")]]のようにコメントも使えるが、コンパイラがどうあつかうかは未定義。
  • 戻り値の型推定:
    • Cの暗黙のintとは違う! return文のオペランドから推測。
    • return文は複数あってもよい。(型はあっていないとだめ)。再帰もok。
    • テンプレートがからむと型を書くのが面倒なのが楽になる。
    • decltypeでもできるが式が重複する。decltype(auto)というのもあるが省略(説明がめんどくさい)。N3638。
  • 変数テンプレート:
    • template value; value=0; value=0.0;
    • 型ごとに精度を変えた数値を用意したいことがある。円周率とか。
    • 関数テンプレートでも同じことがきるが関数呼出のカッコがつくだけ。値を返すメタ関数にも使える。
  • ジェネリックlambda式:
    • auto print = [](auto x){...} 関数オブジェクトのtemplate operator()をlambdaにも持たせる。
    • auto f = [](auto... args){}とパラメータパックもつかる。
  • 汎用lambdaキャプチャ:
    • [初期化子](){...}。
    • non-static data memberがコピーキャプチャできなかった。[=]と書いてもthisがコピーされただけでメンバはコピーされていない。
    • ムーブキャプチャができなかった。unique_ptrをムーブできなかった。
    • [data=data](){}と書く。[p=std::move(p)](){}と書く。[s=data](){}のように名前も変えられる。
  • constexpr(コンストエクスプロォァ〜)関数の制限緩和:
    • constexprの発音は「コンストエクスプロォァ〜」が国際標準らしい。
    • ループは再帰で書かないといけなかった。
    • ローカル変数宣言・変更、条件(if)ができるようになった。普通の人は再帰じゃなくループをつかいたい。

[2013-11-14 20:02]

  • Q: 汎用lambdaキャプチャーでムーブで[&&]でムーブにするのはなめだめだったか?
  • A: より一般的にコピーを用意すれば十分という結論。特殊な文法は入れたくなかった。std::move()をつかえ。
  • Q: exprの読み方
  • A: エクスプレッション・エクスプレ・エクスプルなど
  • Q: constexprでforつかったらコンパイルはどうやって終るような制約はあるのか?
  • A: ない。最悪終わらない可能性がある。
  • Q: 二進数リテラルに3とか書いたら?
  • A: エラーになる(十進数にAと書いたらエラーになるのとおなじ)
  • Q: constexprが標準ライブラリに入らないのは?
  • A: 規格に準拠していないことになるため付けられない。
  • Q: 汎用ラムダキャプチャのリスト初期化の型推論はclangではやってくれないみたいだが。int x=0; [x{x}](){}。
  • A: 型指定の規格が入る予定はない。
  • Q: 実際的にはdynarray<>はスタックからとられることが多いか?
  • A: dynarrayでも静的ストレージからとられることが期待できる。だめかもしれないが。

[2013-11-14 20:13]

休憩

_1120974

[2013-11-14 20:24]

web開発現場のC++11の活用 / ドワンゴ 朝倉輝(あきら)_1120975

  • niconicoでC++がどうつかわれているか。
  • 開発(コード書き)・企画(ディレクタ)・インフラ・デザイナ・テスタ・サポートなどに分かれている。
  • バックエンド開発担当、C/C++,JavaScript,Java,php,AS3,C#...
  • コメントサーバ: コメントの投稿と配信。httpとflash(html socket)に対応。websocketも。C++で実装。
  • 動画配信サーバ: シークバー上にでるサムネイルとか
  • 生放送配信サーバ 根幹はC/C++
  • 超会議2の電子黒板: ストロークと画面を転送
  • バックエンドは速度と安定性を重視。けっこうC++をつかう。
  • win/mac/centos,VS6,a2010-2013,eclips/intelij/flash develop: 社内ではIDEは少数派
  • 本番環境や共通開発環境は開発者は手がだせずインフラ管理になっていて更新はあまりされない。boostのバージョンがばらばらだったり。
    • セキュリティパッチは当ててるよ!
    • 更新しないのは台数多いのと、担当わからないのと、ミスりたくないのと。
    • gccのアップデートはRHELに新しいのが入ってかつハードウェアリプレイスのタイミングで。
    • 新規開発では新しいのがつかえる。scientific linuxとか。でもC++0xどまり。C++11はいつつかるのだろうか...
  • あまり最新機能をつかうとメンテできないのでつかいにくい。
  • 上司: autoをつかうと型がわからない! → IDEつかえばいいじゃん..
  • iteratorだけでもautoつかいたい。
  • rvalueはけっこうたいへんだった。

[2013-11-14 20:39]

  • Q: VS6をつかってたのは?
  • A: それでないとビルドできなかったため。
  • Q: CとC++のつかいわけ基準?
  • A: 一からかくときにはC++でかく。

[2013-11-14 20:43]

休憩

  • ピザ&ビールタイム
  • 順番に後ろのテーブルにピザ・ビールなどをとりにゆくが、最終組は紙皿枯渇のため各自創意工夫しろとの指示が...

_1120976_1120977_1120979

[2013-11-14 20:56]

rvalue reference / 西江みのる_1120978

  • http://prezi.com/bkhxdnuq6qzv/rvalue-reference/
  • C++11つかってない(自由などどこにもない!)
  • 言語くらいは安定させておきたい
  • C++11は意外と壊さないようになっている感じだが
  • もしC++11に移行するとすれば?
  • rvalueはrvalueで初期化できない → 一時オブジェクトに名前つけたら一時オブジェクトじゃないよね〜って説明。
  • ravlue objectは破壊してもよい。
  • 10年前のC++なら swap() をつかうところ。
  • move(): 呼出先でぶっこわしていい宣言.
  • move ctor: 元objにはデストラクタで困らないようにテキトーな値をつめておく。
  • 値のセマンティックスを持つ → コピーのセマンティックスを持つ と言いかえられる。
  • set(string v) にすべき。st(const string& v) よりも。
  • C++03では値渡しは値返しはcopyになるので、pessimization(不適化)だった。
  • C++11ではmoveできるならmoveされる。
  • ctor(const string& v) : v(v) {} → ctor(string v) : v(move(v)) {}
  • moveしないのであればconst refで受けたほうがよい。
  • getterはconst referenceで返した方がよい。

[2013-11-14 21:11]

  • Q: このスライドは?
  • A: flashです!不自由です!
  • Q: rvalue refの感想は?
  • A: rval refとconst refの両方の関数をつくらないといけないのかと悩んだことくらいか(つくらなくてよい)
  • Q: moveに対応してるかどうかテンプレートだとわからないのでは?
  • A: 意味的にcopyすべきときにmoveはしないので悩まないはず。
  • Q: returnでmoveを期待するとRVOとぶつかってしまう?
  • A: RVOはコピーでもムーブでも対応きるはず(単にコンパイラの実装の問題)。
  • Q: moveしたあとにコンパイラが最適化できるか? constでの最適化が制限されてたりするが。
  • A: 一部の文脈では勝手にmoveすることが許されている。rvalueをつかってなくてもコンパイラが勝手に最適化してしまうことはある。
  • Q: 言語設計の問題(早すぎる最適化問題)?
  • A: コピーできないもの(ファイルハンドル)とかで所有権の移動に対応するためにrvalueは必要。コンパイラへのヒントという目論見もあったはず。
  • Q: auto_ptrとの違いは?
  • A: エピスさんがLTでやります!

[2013-11-14 21:23]

休憩

LTタイム

  • 「発表は5分で、5分たつとアラームが鳴るので、みなさん拍手を」とのことで5分で強制終了

[2013-11-14 21:30]

clang-format / @Linda_pp_1120980

  • https://gist.github.com/rhysd/7466359
  • (プレゼンはvim)
  • 開発ではコーディングスタイルがきまっていることが多い。80桁制限とか。
  • 自分のスタイルで書いてから整形するとか、他人のコードを整形してから読むとか。
  • clang-formatはLibFormatを利用してフォーマット変換。

[2013-11-14 21:35]

[2013-11-14 21:40]

Wandbox / @melponn_1120981

[2013-11-14 21:45]

  • Q: みんながレイトレーシングしたらどうなる?
  • A: 30秒で切れます。
  • Q: いたずらされない工夫は?
  • A: chrootとかリソースの制限をかけている。
  • Q: どこでホスティング?
  • A: さくらVPSでHaskell。

[2013-11-14 21:46]

[2013-11-14 21:47]

L丁 / M.Fkukasawa(新人)_1120982

  • http://www.slideshare.net/roentgen_jp/c11-lt
  • atomic(ロックラインベースの同期メカニズム), TLS(thread keyさよなら), fence(メモリバリア)まである
  • closure(lambda): courceすればいいよ
  • closureには暗黙のthisがわたってくる。

[2013-11-14 21:52]

[2013-11-14 21:54]

C++11: unique_ptrを5分ご紹介 / επιστημη_1120983

  • http://www.slideshare.net/ssuser1f23d9/episteme-unique-ptr
  • http://codezine.jp/article/detail/7479
  • CodeZineにのりました
  • auto_ptrはdeprecatedに。
  • make_uniqueがはいる。make_sharedはあったけど。
  • auto_ptrとはちがって配列対応。 unique_ptrと書ける。make_unique(4)とか。
  • '=' では代入できず move() をつかう。auto_ptrは=でmoveになってた。
    • unique_ptr& operator=(const unique_ptr&) = delete;になっている。
  • default_deleteを置き換えられる。deleteの代りにfcloseよ呼ぶとか。lambda式指定できる。

[2013-11-14 21:59]

_1120984

あまっていたビールを1缶もらって帰途に。新橋に出て東海道線 茅ヶ崎経由で相模線。

_1120985_1120986_1120987_1120988_1120989_1120992

make_shared

make_sharedのつかいかたを調べようとしたらstd::make_shared ~ただのヘルパじゃない!というのをみ、make_sharedをつかうとメモリをひと塊でallocateしてくれることを知った。 速くなってるらしいし

確認ってことで、こんなプログラムをつくってみて

#include <memory>
#include <cstdlib>
#include <iostream>

void* operator new(size_t sz) { std::cout << sz << std::endl; return malloc(sz); }
void operator delete(void* p) { free(p); }

struct A {
    char buf[1000];
    A() {}
};

int
main()
{
    std::cout << "make_shared" << std::endl;
    auto a = std::make_shared<A>();
    std::cout << "---" << std::endl;

    std::cout << "new+shard_ptr" << std::endl;
    std::shared_ptr<A> a2 (new A);
    std::cout << "---" << std::endl;

    for (;;) ;
}

実行

% g++47 -std=gnu++0x -g foo.cc
% ./a.out
make_shared
1032
---
new+shard_ptr
1000
24
---
^C

ヘッダファイルをみても詳細は理解できなかったが、実行結果からは確かにカウンタとオブジェクトを一緒にallocateしている。

これが理由でmake_sharedにdeleterを指定できないんだろうなぁ、きっと。

スタティック変数をテンプレートパラメータにできない(理由不明)

グローバル変数のポインタをテンプレート引数にした場合はコンパイルできる:

http://ideone.com/VV3wo

スタティック変数だとNG:

http://ideone.com/NNt9u

unnamed namespace(static変数の代替)だとOK:

http://ideone.com/GLvyI

2011/06/03 15:14:35
@subarug 質問です! これ http://ideone.com/NNt9u ってなんでだめなんでしょう? http://ideone.com/VV3wo http://ideone.com/GLvyI はいけるんですが。

2011/06/03 15:16:22
@koie エラーメッセージに書いてある通りじゃないですかね.

2011/06/03 15:27:28
@koie とりあえず,名前空間直下での static は deprecated なので,使わないほうがいいと思います.

第5回ありえるえりあ勉強会 ~「Lisp脳」勉強会 ~

私にはレベルが高くてついてゆくのがやっとでした。以上感想おわり。

Lisperの見る世界 / 深町英太郎

Emacs Lisp脳と Haskell脳 / 山本和彦

Lisp脳とかやめよう / 佐野匡俊

C++が仲間になりたそうにこちらを見ている

)の品格 / @emasaka

公式まとめ


  • 0dbe46d6.jpg
  • 85a582c5.jpgトイレからの眺め
  • f4d208f2.jpg会場の様子(途中休憩時に撮影)

shared_ptrと配列

valgrindでプログラムを調べてたら怒られて気づいたんだが、 shared_ptr<T>(new T[n])のようにshared_ptrで配列を持つと消すときにdelete pが呼ばれるので問題である。 new T[n]でつくった配列はdelete[] pで消さないといけない。 boostにはshared_arrayというものがあるらしいが、そういうのはtr1の下にないので、 こんなdeleterをつくって回避した。
template <typename T>
struct array_deleter
{
    void operator()(T* p) const { delete[] p; }
};
void
f()
{
    shared_ptr<int> p (new int[999], array_deleter<int>());
}

Boost.勉強会 #2

c414201d.jpg20a2ea03.jpg

12:55〜13:00 : 会場の案内 (ももい)

会場貸します。ただしIIJ関係者がいることが条件。平日夜はけっこう空いてるらしい。 のってきそうなネタなら会社帰りに参加できるのでだいじょうぶ。

oss-contact@iij.ad.jp

13:00〜13:20 : Boostライブラリ一周の旅 1.41.0〜1.44.0までの差分 (faith_and_brave)

property tree
  • xml,json.ini
  • RapidXmlをつかっている。
  • .attrはつかえない点に注意。
uuid
  • randomとstringから生成できる。
range
  • range algo: iterの組からrangeがつかえるようになった。(ちょっとべんりになっただけ)
  • range adapter: pipeっぽくつないでなんかできる。 m | map_keys でキーだけぬきだ したり。
  • 遅延評価がされるのでベンチマークがとりにくいらしい。
  • Range2.0はおすすめ。Oven Rengeってしゃれたネーミングらしい。
filesystem
  • v3で日本語対応。string,wstringのかわりにpathをつかう。これからのながれか。
polygon
  • 三角形の中の判定ができたり。
meta state machine (MSM)
  • state chartのかわり。
  • boost::mpl::vectorで一箇所に記述できる(あちこちにちらばらなくてよい)

13:30〜14:00 : Boost.Graph (egtra)

  • 頂点vertexと辺edge
  • linked-list, tree
  • directed, undirected
  • adjacency_list<>
  • JR最長片道切符をBoost.Graphで総当たりした。
    • 北海道の路線を打ち込んだとこでギブアップ...
    • 四国が路線はすくないけど最長切符の区間にはいらないことが知られている...
  • なんでgraphをつかうか?
    • イテレータがつかえるからとかrangeっぽいのがあるから。
    • malloc/forのかわりにstlがつかえるから。
  • VC2010でテンプレート引数でミスると赤線がひかれて便利!らしい。

14:20〜14:50 : Boost.GIL (Leo)

  • Leoは本名。
  • ギル、ジル、ギーアイエル? 開発者はジーアイエルといっているらしい。
  • 色空間重要。3種類だけサポート。
  • ラスタ画像のみサポート。(ベクタはなし)
  • 画像の操作にはImave Viewをつかう。Imageはいじらない。
  • ピクセルへのアクセスは
    • image_view::operator() 絶対座標
    • iterator 順番にアクセス
    • locator 相対位置
  • テンプレート引数が長くなりがちでめんどい。
  • 動体検出 = フレーム間の差分(引き算)
  • 演算するときは for(y) for(x)の順にやるのがふつう。
  • stlcv: STL like OpenCV wpraeerというのもある。
  • 差分を表示するviewってのを作るとよさそうだが内部を知ってないと難しい。
  • viewで変換したのもはimageにcopyすれはいつでも保持できる。
  • ぼかしなどもできるけどファンクタを書く必要がある。
  • 自分で画像サポートを書こうとすると自分で圧縮を解く必要がある。
  • 画像フォーマット(jpeg?depth?)を調べるのはユーザがやる。てきとうに変換してくれ はする。depthとか。
  • ジェネリックなコードなので色空間を切り替えるのはかんたん。
  • 新しい色空間をサポートをするのはそれほどたいへんではない。HSV拡張は自分で書い てみた。参考にして。
  • rgb8_image_tはboostっぽくないけど、rgb8_image_tは展開すると画面いっぱいになる ほどテンプレートパラメータがいっぱいある。なのでdepthをとりだしすことはできる。
  • 複数のviewをかさねてもコスト0。回転なんかはポインタの操作だけなのでコスト0らしい。色空間の変換だけがコストがかかるらしい。
    • 実はコスト0というのは手で書いたのと比較してという意味らしい。なので実行コストかかる。
  • const View にたいして view(x,y) = xxx とかできる。(constなのに!)
    • constなのは設定に対して。
    • rbg8c_image_tにするとconstなイメージになる。

15:00〜15:50 : SEXYHOOK (rti)

(略)

16:05〜16:40 : Boost.Flyweight (SubaruG)

  • const教
  • immutableはtemplateで実現できる。
  • shared_ptr
  • flyweightは等値のものを1つにまとめる。基本はshared_ptrと同じ。
  • const -> immutable -> shared_ptr -> flyweight ってながれ
  • 非侵入的なので boost::flyweightとかできる。
  • パフォーマンス: 構築はややおそい。コピーや比較は高速。ハッシュ関数としてアドレスがつかえるのでunorderd_mapとかに。ただしハッシュfunctorは自分でつくる。文字列なんか便利かも。
  • デメリット:
    • 非侵入的なので最適化に限界がある。
    • flyweight側からその言語のGCがつかえない。
    • シリアライズしたときにハッシュ値=アドレスがかわるのはいやかも。文字列にハッシュ値をうめこむのもあり。
  • trieをつかうと効率化できそう!
  • key-value flyweight
    • flyweight>
    • つくるときはflyweightでつかうときはflyweight → Valueの制作は遅延される
  • 公式ページがよくできている。
  • Linux kernelだとmemory のdedupとかあるけど、小さなオブジェクトではflyweightは 有効はなず。メモリ以外の資源も共有できるし。
  • 複数の名前空間をサポートしていてタグをつかうとできる。
  • notrackだとresetできない。bome GCがあれば別だけど。

16:50〜17:35 : MessagePack for C++ (frsyuki)

  • mplex: C++のプログラムを生成するライブラリ。
  • json, protocol buffersよりもはやい。文字列のzero copyが効いている。
  • V-FIELD,Cagra, KAstor,kumofsなど何度もRPCを書いてきた..
  • streaming deserialization
  • future = client.call_async(...);
  • 最適化
    • コンテナ型: type length bodyをシリアライズ
    • コンテナでない型: type valueのみ
  • messagepackの型システム(=json)があってハブになっていて、各言語と変換する。
  • json-RPCベース: 種類はrequest,response,notify(one-way)。msgidがいっている。
  • 特徴
    • async rpc
    • paralllel pipelining
    • thrifft IDL
    • dynamic typing
    • connection pooling
    • delayedreturn
    • event-drivend
  • event loopはmpioつかっている(C++),RubyではRev,JavaはXNIO。IO,timer,signalを1つのevent loopで対応できる。
  • message pack platform構想
    • 分散DB, 分散ストレージ、分散キャッシュ、分散キューなどひとまとめにしたmessage pack platformを構想中
  • フォーマットはbig endianでUTF-8。
  • floatの配列はやっぱりほしい。25%サイズが増えてしまう。型がいっしょだったら型情報を省略とか。要望はあちこちからあるが、できるだけ単純なものにしたいため手をつけていない。
  • iteratorでアクセスできるようになるとboostっぽい。
  • RPCにrequired,optionalなフィールド指定ができない(現在実装中)
  • エラーはいまはerror,timeoutしかない。
  • optional<>対応はちょっと難しい。voidを返すようになっているため。
  • androidではC++は例外がつかえない! (コーディング規約の問題だけっぽい)

17:45〜17:45 : バベル (wraith13)

  • 文字エンコーディング変換モジュール
  • 日本語限定なのでエンコーディング判定制度が高い。
  • AIXでもうごく移植性。
  • 「〜」対応とかやってる。

17:55〜18:15 : Boost.Interface (melpon)

  • templateでduck typingできるけどコンテナにいれらない。
  • boost::interfaces::shared_ptrでもちはこぶ
  • shared_objもある。
  • 例外をなげて型を調べているらしい。

ソノタ

  • WiMAXはちょっと弱いけど使えた。
  • 女装率高し 2%?
  • 魔導書はとぶように売れて完売だった模様
  • 10分の休憩があるのでラクだった。
  • ちっちゃい字が読めない。めがねをあたらしくした方がいいかな。
  • 黒地だと文字がみにくいからやめてほしい
  • 会場アンケートによるとLL系とはかぶってなさげ。並列カンファレンスの人たちとはかぶり度がたかいようだ。
  • redbullをのんでる人ちらほら
  • プレゼンだとautoをつかうとすっきりするけど、型がわからなくなる欠点もある。

C/C++のエラー処理パターン

Cだとgotoをつかうのが基本。C++だとtry/throw/catchもあり。 めんどくさいのが、atomicオペレーションを実装するときに、内部で副作用があちこちに発生して 途中で失敗したら取消てまわらないといけない場合。 正常系はこんなかんじだとして
int
main(int ac, char **av)
{
    int rc = 1;
    int x = av[1] ? atoi(av[1]) : 0; /*atoiのエラーはみぬふり*/
    f(x); /*エラーをおこすかも*/
    g(x); /*エラーをおこすかも*/
    return 0;
}

Cのgotoパターン。
#include <iostream>
#include <cstdlib>

using std::cout;
using std::endl;

int a = 0;
int b = 0;
void
show()
{
    cout << "a=" << a << endl
         << "b=" << b << endl;
}

int
f(int x)
{
    if (x > 100)
        return -1;
    a += x;
    return 0;
}
void
undo_f(int x)
{
    a -= x;
}

int
g(int x)
{
    if (x > 10)
        return -1;
    b += x;
    return 0;
}

int
main(int ac, char **av)
{
    int rc = 1;
    int x = av[1] ? atoi(av[1]) : 0;
    if (f(x) < 0)
        goto err_f;
    if (g(x) < 0)
        goto err_g;
    rc = 0;
    goto out;

 err_g:
    undo_f(x);
 err_f:
 out:
    show();
    cout << "rc=" << rc << endl;
    return rc;
}
g(x)が失敗したf(x)を取り消すためにundo_f(x)を呼び出す必要がある。 副作用をおこすブロック(この例だとf()とかg())毎に対応する gotoラベルを用意してリカバリルーチンを逆順に呼んでいく。 問題はf(),g()の部分とリカバリの部分がコード上で離れてしまうのと 逆順に書くの人間がやらないといけないところ。f()とg()の順序が逆になったときや f()とg()の間にh()が入ったときにリカバリ部分も書き換えないといけない。 たぶん書き換えるのは忘れないとおもうが、実装ミスをする個所が増える。
C++の例外処理をつかった例
#include <iostream>
#include <cstdlib>

using std::cout;
using std::endl;

int a = 0;
int b = 0;
void
show()
{
    cout << "a=" << a << endl
         << "b=" << b << endl;
}

struct ERR {};

void
f(int x)
{
    if (x > 100)
        throw ERR();
    a += x;
}
void
undo_f(int x)
{
    a -= x;
}

void
g(int x)
{
    if (x > 10)
        throw ERR();
    b += x;
}

int
main(int ac, char **av)
{
    int rc = 1;
    int x = av[1] ? atoi(av[1]) : 0;
    try {
        f(x);
        try {
            g(x);
            rc = 0;
        }
        catch (ERR&) {
            undo_f(x);
        }
    }
    catch (ERR&) {
    }
    show();
    cout << "rc=" << rc << endl;
    return rc;
}
tryブロックの入れ子で実装している。gotoパターンに比べて、正常系の処理とエラーリカバリの処理とが 構文上のブロックとして関連づけられるのでミスが減るが、外のtryブロックほどcatchブロックが離れてしまうので コード上の見通しがわるくなる。
おなじく例外処理をつかう別の例
#include <iostream>
#include <stdexcept>
#include <cstdlib>

using std::cout;
using std::endl;
using std::exception;
using std::runtime_error;

int a = 0;
int b = 0;
void
show()
{
    cout << "a=" << a << endl
         << "b=" << b << endl;
}

struct ERR {};

void
f(int x)
{
    if (x > 100)
        throw ERR();
    a += x;
}
void
undo_f(int x)
{
    a -= x;
}

void
g(int x)
{
    if (x > 10)
        throw ERR();
    b += x;
}

void
proc2(int x)
{
    try {
        g(x);
    }
    catch (ERR&) {
        throw;
    }
}

void
proc1(int x)
{
    f(x);
    try {
        proc2(x);
    }
    catch (ERR&) {
        undo_f(x);
        throw;
    }
}

int
main(int ac, char **av)
{
    int rc = 1;
    int x = av[1] ? atoi(av[1]) : 0;
    try {
        proc1(x);
        rc = 0;
    }
    catch (ERR&) {
    }
    show();
    cout << "rc=" << rc << endl;
    return rc;
}
1関数1処理に限定するように書くことで構文上のtryの入れ子を避けている。 呼び出し関係から実際にはtryは入れ子になっている。
C++0xで入るlambdaをつかった例
#include <iostream>
#include <stdexcept>
#include <cstdlib>

using std::cout;
using std::endl;
using std::exception;
using std::runtime_error;

int a = 0;
int b = 0;
void
show()
{
    cout << "a=" << a << endl
         << "b=" << b << endl;
}

struct ERR {};

void
f(int x)
{
    if (x > 100)
        throw ERR();
    a += x;
}
void
undo_f(int x)
{
    a -= x;
}

void
g(int x)
{
    if (x > 10)
        throw ERR();
    b += x;
}

template <typename F>
struct cmd
{
    F* pf;
    cmd(F& f) : pf(&f) {}
    ~cmd() { if (pf) (*pf)(); }
    void clear() { pf = 0; }
};
template <typename F>
cmd<F>
make_cmd(F f)
{
    return cmd<F>(f);
}

int
main(int ac, char **av)
{
    int rc = 1;
    int x = av[1] ? atoi(av[1]) : 0;
    try {
        f(x);
        auto uf (make_cmd([&x]() { undo_f(x); }));
        g(x);
        uf.clear(); //gが成功したらfのundoは不要。
        rc = 0;
    }
    catch (ERR&) {
    }
    show();
    cout << "rc=" << rc << endl;
    return rc;
}
記事検索
月別アーカイブ
アクセスカウンター

    タグ絞り込み検索
    ギャラリー
    • 今日の練習 2024-12-05
    • 今日の練習 2024-12-05
    • 今日の練習 2024-12-02
    • Zoff: メガネの上からかけられるオーバーグラス(偏光機能搭載)
    • Zoff: メガネの上からかけられるオーバーグラス(偏光機能搭載)
    • Zoff: メガネの上からかけられるオーバーグラス(偏光機能搭載)
    Amazon
    楽天市場
    adby google
    LINE読者登録QRコード
    LINE読者登録QRコード