1 名前:デフォルトの名無しさん (ワッチョイ dfcf-HvS5) mailto:sage [2017/01/09(月) 14:49:27.56 ID:p96WJVyd0.net] 次スレを立てる時は本文の1行目に以下を追加して下さい !extend:on:vvvvv:1000:512 C++に関する質問やら話題やらはこちらへどうぞ。 ただし質問の前にはFAQに一通り目を通してください。 IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。 前スレ C++相談室 part128 echo.2ch.net/test/read.cgi/tech/1480172629/ このスレもよろしくね。 【初心者歓迎】C/C++室 Ver.100【環境依存OK】 echo.2ch.net/test/read.cgi/tech/1478440682/ ■長いソースを貼るときはここへ。■ codepad.org/ https://ideone.com/ [C++ FAQ] https://isocpp.org/wiki/faq/ www.bohyoh.com/CandCPP/FAQ/ (日本語) VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured
652 名前:デフォルトの名無しさん (スプッッ Sdb2-K8Mp) mailto:sage [2017/03/15(水) 17:59:26.07 ID:wfaQCMr9d.net] >>634-636 たすかりもうした おかげでコード上手くかけたので助かりました
653 名前:デフォルトの名無しさん (ワッチョイ 133c-v8EU) [2017/03/16(木) 18:08:57.23 ID:KOsUwnSu0.net] テンプレートの特殊化を勉強しているんだけど https://ideone.com/Z7enCI これがなんでエラーになるのか教えてください
654 名前:デフォルトの名無しさん (ワッチョイ ef6c-i8cA) mailto:sage [2017/03/16(木) 18:18:50.30 ID:ZMIdRLMQ0.net] >>639 intのHogeのFoo関数のtemplate<>が余計 Hoge<int>が特殊化されていることはクラス側でわかっているため
655 名前:デフォルトの名無しさん (ワッチョイ 133c-v8EU) [2017/03/16(木) 19:00:18.20 ID:KOsUwnSu0.net] >>640 なるほど、サンクス
656 名前:デフォルトの名無しさん (ワッチョイ 133c-v8EU) mailto:sage [2017/03/17(金) 09:32:55.95 ID:OqtFMBfF0.net] 関数のアドレスを取得するときに クラスのメンバじゃない普通の関数は&をつける必要がないのに メンバ関数は&をつけないといけなくなる理由を教えて
657 名前:デフォルトの名無しさん (ワッチョイ 5319-v8EU) mailto:sage [2017/03/17(金) 09:40:10.52 ID:Wd4E8hAa0.net] ideoneで書いてると急に初期化されて初めの状態のコードに戻ってしまうのですが わたくしだけでしょうか?
658 名前:デフォルトの名無しさん (スップ Sddf-8YZg) mailto:sage [2017/03/17(金) 11:36:52.60 ID:c9xwv7oqd.net] >>642 言ってる意味がよくわからん
659 名前:デフォルトの名無しさん (ワッチョイ 3fdf-8FG5) [2017/03/17(金) 13:16:36.04 ID:AO+9LJwo0.net] >>642 ドライに言うと、規格でそう決まっているから なんでそう決まっているかというと、 メンバポインタ(関数に限らない)取得は特殊な行為で、 インスタンス内のメンバの絶対アドレスを取得するが一般的な行為*1なので、 特殊な行為は明示的*2に書こうということになっている struct asshole { void sonofabitch(int) { } void dipshit() { auto jerk = sonofabitch; } }; ↑は現実にはコンパイルエラーだが、もし通すとしたら おまえ的にはjerkには何が入るべきだと思う? ちなみに俺はbind(&asshole::sonofabitch, this, _1)に見えちまう *1 俺じゃなく禿がそう思っている *2 アドレス演算子とスコープ演算子が必須
660 名前:デフォルトの名無しさん (ワッチョイ bf27-tpgq) mailto:sage [2017/03/17(金) 13:48:45.02 ID:l8NCqXAU0.net] どこをどうひねるとそういう煌びやかな単語が出てくるのかが謎
661 名前:デフォルトの名無しさん (ワッチョイ 5319-v8EU) mailto:sage [2017/03/17(金) 16:09:10.13 ID:Wd4E8hAa0.net] ダブルヂスパッチってwikipediaだと2つのオブジェによってヂスパッチ する意味ってかいてあるけれどwikipedia以外のホムペには2回ヂスパッチすること って書いてあるばあいもありますね。
662 名前:デフォルトの名無しさん (ドコグロ MMb7-3fK7) mailto:sage [2017/03/17(金) 18:32:57.86 ID:dpI1G6OFM.net] >>645 日本語がまともに書けるようになってからレスしなよ
663 名前:デフォルトの名無しさん (ワッチョイ bfda-8FG5) [2017/03/17(金) 19:46:28.78 ID:sgxnbWig0.net] >>648 おまえは批判がまともに書けるようになるまでROMってろ
664 名前:片山博文MZ ◆T6xkBnTXz7B0 (スププ Sddf-W8JT) mailto:sage [2017/03/17(金) 19:54:05.38 ID:+s8GChIVd.net] 批判
665 名前:デフォルトの名無しさん (ワッチョイ bf3c-5NuA) mailto:sage [2017/03/17(金) 19:59:12.76 ID:KNcySIzq0.net] >>648 俺は普通に理解できたんだが、逆になにが悪いのか教えて欲しい。
666 名前:デフォルトの名無しさん (ブーイモ MM37-nFTW) mailto:sage [2017/03/17(金) 21:49:19.82 ID:YstDK/amM.net] メンバー関数のアドレス取得も絶対アドレスだと思うんだけど
667 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/17(金) 22:10:36.61 ID:Kkd83n1s0.net] >>646 ○○がマイブームな年頃 うんち:3さい カンチョー:6さい サノバビッチ:14歳←英語使ってる俺カッコイイ とかじゃね? ところで脱線するが、>>645 でbindがC++にあることを初めて知ったのだが、 thisをバインド出来ているがこれって意味あるのか? JavaScriptみたいな動的ダックタイピングなら継承関係なくbind出来るので意味があるのだが、 C++なら継承してないとbind出来ないよな? だったら最初からインスタンスのポインタを管理して普通にメンバ呼んだ方が楽だと思うが。 (継承してないとbind出来ないのなら管理対象のポインタが 関数ポインタになるかインスタンスになるかだけ。 実質的なプログラミングコストは変わらない)
668 名前:デフォルトの名無しさん (ワッチョイ 133c-v8EU) [2017/03/17(金) 22:24:44.25 ID:OqtFMBfF0.net] >>645 ごめん、bind関数の理解があいまいなんだが 要するにインスタンス先のsonofabitchメンバ関数になるように見えるって言いたいんだよね 俺は(も?)そう思った でも規格で決まってるって一言で言ってもらえてなんとなく割り切れた ひとつだけ 「インスタンス内のメンバの絶対アドレスを取得する」のが特殊な行為って部分をkwsk 他のポインタは相対アドレスなの?
669 名前:デフォルトの名無しさん (ワッチョイ 3398-jYbd) mailto:sage [2017/03/17(金) 22:41:33.75 ID:pMlN+j4d0.net] いやでも、原文には >インスタンス内のメンバの絶対アドレスを取得するが「一般的」な行為 って書いてあるし
670 名前:デフォルトの名無しさん (オッペケ Sr97-w0Gz) mailto:sage [2017/03/17(金) 23:23:01.06 ID:p3X8pgmur.net] >auto jerk = sonofabitch; ここは話の流れでは auto jerk = asshole::sonofabitch; とすべき所を、勝手に「asshole::」を取って話をすり替えるとは
671 名前:デフォルトの名無しさん (ワッチョイ a342-W3uL) mailto:sage [2017/03/17(金) 23:23:58.39 ID:lHYxcE7d0.net] >>653 transformみたいなアルゴリズム系の関数に渡すときにバインドするしかないだろ
672 名前:デフォルトの名無しさん (ワッチョイ 3fd1-h49x) mailto:sage [2017/03/17(金) 23:46:36.67 ID:KqZX+Igl0.net] 継承してなくてもbindできるでしょ
673 名前:デフォルトの名無しさん (ワッチョイ 537b-gO1F) [2017/03/17(金) 23:48:26.71 ID:RKn5d9hw0.net] 継承とbindがどう関係すんのか解らんわ
674 名前:デフォルトの名無しさん (オッペケ Sr97-w0Gz) mailto:sage [2017/03/18(土) 09:12:06.02 ID:QtoorQPlr.net] >>653 >C++なら継承してないとbind出来ないよな? 継承の意味もわからないレベルはすっこんでた方がいい ideone.com/Wl7A59
675 名前:デフォルトの名無しさん (ワッチョイ f3e7-ajdi) mailto:sage [2017/03/18(土) 09:44:46.57 ID:g4V8rpJk0.net] ふえーん。VC++でW系のこーどがわからないよ〜。
676 名前:デフォルトの名無しさん (ワッチョイ f3e7-ajdi) mailto:sage [2017/03/18(土) 09:54:09.70 ID:g4V8rpJk0.net] C++のバグかと思ったら、いじってるHTMLのバグだった。悲しい。
677 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/18(土) 11:02:56.09 ID:waR+gchT0.net] >>657 std::transformならbindいらんだろ。イテレータを渡してる。 > https://cpprefjp.github.io/reference/algorithm/transform.html そしてこの場合、(someClass->*someMethod) と書けるしそれで十分だろ。 >>660 ここでbindも継承もないソースを上げてくることにびっくりだわ >>658-659 関数内でのthis.someFieldへのアクセスは継承してないと無理でしょ。 静的型ではポインタを生成出来ない。(動的ダックタイピングなら可能) www7b.biglobe.ne.jp/~robe/cpphtml/html03/cpp03057.html www.ibm.com/support/knowledgecenter/ja/SSGH3R_12.1.0/com.ibm.xlcpp121.aix.doc/language_ref/cplr034.html 継承してない物をbindして、その関数内からthis.someFieldにアクセス出来る例があるか? あればよろしく。
678 名前:デフォルトの名無しさん (ワッチョイ 838b-UnlH) mailto:sage [2017/03/18(土) 11:43:31.57 ID:YXP7lJmh0.net] ていうか仮想関数(による多態性)とテンプレート(によるfunctor)がどっちも使える状況で どうしてもメンバ関数のアドレスをとる必要があるというシチューエーションとは一体、 ちなメンバ関数のアドレスをとる構文は覚えていない 主記憶にございません
679 名前:デフォルトの名無しさん (ワッチョイ 838b-UnlH) mailto:sage [2017/03/18(土) 11:45:58.26 ID:YXP7lJmh0.net] 誤:テンプレート(によるfunctor) 正:テンプレート(へのfunctorとかクロージャ渡し)
680 名前:デフォルトの名無しさん (ワンミングク MM5f-W3uL) mailto:sage [2017/03/18(土) 12:01:44.38 ID:TmvAgLdoM.net] >>663 もういいから死ね https://ideone.com/jZNd95
681 名前:デフォルトの名無しさん (ワッチョイ 838b-UnlH) mailto:sage [2017/03/18(土) 12:41:56.92 ID:YXP7lJmh0.net] f.calc(x, 2)をfunc(x)として呼びたいためだけにstd::bind()を使うのはメリット感に欠ける…
682 名前:デフォルトの名無しさん (ワンミングク MM5f-W3uL) mailto:sage [2017/03/18(土) 12:43:09.53 ID:TmvAgLdoM.net] >>667 できるできないの議論だから
683 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/18(土) 12:48:15.84 ID:waR+gchT0.net] >>666 > std::vector<int> invoke(const std::vector<int>& v, const F& f) const > std::bind(&F::calc, f, _1, 2)); bindしている対象は F& f つまり自分自身のクラスだろ。 それは継承してるのと意味は同じだよ。(今回の問いにおいては) 俺はそこに全く無関係のクラス class G{} を突っ込めるのかと問うている。 C++では出来ないだろ。(JavaScriptでは出来る) 自分自身、または継承関係のあるクラスなら、 > std::bind(&F::calc, f, _1, 2)); のところを代わりに f->*calc と書けるんだよ。それでいいだろ、という話。 今回は引数が複数個で、第2引数を確定させたいみたいだから、 C++にその文法が無く、部分適用関数をあらかじめ用意するしかないようだけど、 それは文法が足りてないから。(ただしそこまで使わないのでbindでもいいが) ただそもそもカリー化して一個ずつ食えって話だろ、本来は。 その場合なら第2引数を確定させた関数を作る為に、 class H: F{ int k; int calc(const int x); } だろ。それで h->*calcで良いんだよ。(継承関係が有ればbind無しで書ける) というか内部的には同じ事をやっていると思っているんだが。
684 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/18(土) 12:48:34.92 ID:waR+gchT0.net] それで話を戻すと、 「継承関係無しで、自分自身でもないクラス G をbind出来るか?」 というのが俺の問いね。 お前は日本語にもこだわるタイプのようだから、「自分自身でもない」と明記しておく。 (これは普通に分かると思いたかったが) 要するに俺は、 「静的型であるC++に於いてthisのバインドって意味あるのか?」 と問うている。 動的型ならバインド後にメンバ追加して実行時に揃っていればダックタイピング可能だから意味がある。 静的型はバインドする時点でメンバが揃っていることを確定出来ないといけない。 それって要するに継承関係がないと無理だよね?という話。
685 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/18(土) 12:51:40.31 ID:waR+gchT0.net] × 静的型はバインドする時点で ○ 静的型はバインドが使われているソースをコンパイルする時点で 一応訂正しとくわ。分かる範囲だとは思うが。
686 名前:デフォルトの名無しさん (ワンミングク MM5f-W3uL) mailto:sage [2017/03/18(土) 13:01:24.39 ID:TmvAgLdoM.net] 何が言いたいのか全然わからん とりあえず、そのJavaScriptでできると主張しているコードを晒せ 第一引数にthisをバインドする意味って、内部的にはメンバメソッドはオーバーロード(+マングリング)で解決されるんだから、バインドしとかないと動かねーだろがよ
687 名前:デフォルトの名無しさん (ワッチョイ 2322-ghbJ) mailto:sage [2017/03/18(土) 13:17:03.94 ID:WJ1Bgcsq0.net] std::list<std::function<void<void>>> funcs; A a; B b; callbacks.push_back(std::bind(&A::func, &a)); callbacks.push_back(std::bind(&B::f, &b)); for(auto func : ...) func(); こういう使い方のbindの場合継承は関係ないと思う
688 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/18(土) 13:31:02.22 ID:waR+gchT0.net] >>672 > バインドしとかないと動かねーだろがよ その通りだ。 多分君はC++しか知らないから、それ前提で話をしているからそう思えるのだと思う。 これ自体は不思議ではない。 JavaScriptなら以下みたいなことが出来る。 var a = { a: 1, k: 2, calc: function(x){return this.k*x+this.a;} }; var b = {}; // bはaと継承関係なし var b_calc = a.calc.bind(b); // aのcalcにbをバインド ---(A) b_calc(3); // 実行可能、結果は NaN ---(B) b.a = 4; b.k = 5; b_calc(6); // 実行可能、結果は 34 ---(C)
689 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/18(土) 13:31:20.02 ID:waR+gchT0.net] C++から見ればデタラメだが、JavaScriptはこれでも動く。 C++は(A)の時点でバインド対象(今回はb)がcalcを動かしても問題ないことが必要で、 コンパイル時に確定させる為には通常は継承関係がないと無理だろ。 JavaScriptはそういうの関係無しにとりあえずbind出来る。 ただし中身が揃っていない時に実行したらNaNが返ってくる。(B) そして中身を揃えたあとには正しく実行される。(C) だからJavaScriptみたいな言語ならthisをバインドする意味があるのだが、 C++のように継承関係がないとメンバ関数を呼べないのなら、 常に f->*calc の形で記述することが可能であり、bind時にthisを確定させる意味がない。 (やってもいいのだが、冗長=糖衣構文) JavaScriptでは(B)の時点で b はメンバを何も持っておらず、 (C)の時点でもメンバは a, k のみで、calcはメンバではないことに注意。 (当たり前だが a を継承していれば calc もメンバになる)
690 名前:デフォルトの名無しさん (ワッチョイ 537b-gO1F) [2017/03/18(土) 13:32:09.09 ID:ux+WuUO90.net] >>670 thisに限らずbindするメリットは呼び出し側が(bindで引数を合わせることにより)実際に呼び出される物がどんな関数のか気にせずに呼び出せることっていうのは解るよね? それで、thisのbindだけ疑問視する理由は?
691 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/18(土) 13:38:41.49 ID:waR+gchT0.net] >>673 > callbacks.push_back(std::bind(&A::func, &a)); これを、this側が関係ない奴、例えばBにして、 callbacks.push_back(std::bind(&A::func, &b)); // (D) だとコンパイル通らないだろ?(俺の予想だが) だったら、常にその場合は、 callbacks.push_back(a->*func)); と書けるよね?という話。 (もちろん糖衣構文ならそれでいいんだが) JavaScriptは(D)でも
692 名前:Rンパイル通るんだよ。(まあコンパイル自体がないんだが) そして実行も出来る。(ただし実行時にメンバが揃ってない時にはお察しで) [] [ここ壊れてます]
693 名前:デフォルトの名無しさん (ワッチョイ 537b-gO1F) [2017/03/18(土) 13:48:07.93 ID:ux+WuUO90.net] >>677 つまり >callbacks.push_back(a->*func)) と書けるようにしたらbindでthis使う必要ないって話? そうなのであれば callbacks.push_back([&]{a.func();}); と書けるから別に要らない
694 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/18(土) 13:53:42.63 ID:waR+gchT0.net] >>676 見やすさの為に、というのはいい。 > thisのbindだけ疑問視する理由は? プログラミングコストが減ってないから。 auto a_func = std::bind(&A::func, &a) なら、 a を管理するか a_func を管理するかで、何も隠蔽出来てないし減ってない。 ただ>>673 みたいな使い方だと、 型を揃えた結果、同じ記述で実行出来るから、この点は確かにメリットはある。 これを言いたかったのか?
695 名前:デフォルトの名無しさん (ワッチョイ 537b-gO1F) [2017/03/18(土) 13:59:12.74 ID:ux+WuUO90.net] >>679 bindを使う利点なんてそれしか無いと思うんだけど…
696 名前:デフォルトの名無しさん (ワンミングク MM5f-W3uL) mailto:sage [2017/03/18(土) 14:02:09.89 ID:TmvAgLdoM.net] >>674 C++では、お前があとからやってるインスタンス構築を先にやっとけよってだけの話
697 名前:デフォルトの名無しさん (ワンミングク MM5f-W3uL) mailto:sage [2017/03/18(土) 14:03:34.16 ID:TmvAgLdoM.net] >>679 type_erasureの話がしたかっただけ? C++のこと知らねーなら議論の余地がなさすぎ JavaScriptスレいけよ
698 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/18(土) 14:04:04.03 ID:waR+gchT0.net] >>678 ちょっと輻輳してて申し訳ないが、 > >callbacks.push_back(a->*func)) > と書けるようにしたらbindでthis使う必要ないって話? そう。というか継承関係ある状態でしかメンバ関数使えないのなら、 thisをbindする意味がないと思った。 (引数はbindしていいが、これもbindなしで継承でも書ける>>669 ) ただし、>>673 みたいに、「戻り値と引数が同じなら同じ関数型」として扱えるのなら、 継承関係なしのA::funcとB::funcを同じに扱えるからやっぱbindしてないと駄目だな。 ところで、ここでクロージャを使うことに意味はあるのか? > callbacks.push_back([&]{a.func();}); もちろん使ってもいいが、a.funcがクロージャ内の変数を捕捉しているはずもないし、直接 > callbacks.push_back(a->*func)); で全く問題なくね?
699 名前:デフォルトの名無しさん (ワッチョイ 2322-ghbJ) mailto:sage [2017/03/18(土) 14:06:49.68 ID:WJ1Bgcsq0.net] 正直 std::function<...> f[] = a.func; で書けるなら書きたい 書けないからbind使ってる
700 名前:デフォルトの名無しさん (ワッチョイ 2322-ghbJ) mailto:sage [2017/03/18(土) 14:07:07.58 ID:WJ1Bgcsq0.net] []いらない
701 名前:デフォルトの名無しさん (ワッチョイ a30e-BL3h) mailto:sage [2017/03/18(土) 14:10:17.22 ID:JpaAP8SC0.net] 今時bind使わずlambdaで済ますよね
702 名前:デフォルトの名無しさん (ワンミングク MM5f-W3uL) mailto:sage [2017/03/18(土) 14:10:36.75 ID:TmvAgLdoM.net] >>683 aをキャプチャする必要が有るだろうが まじでclassとインスタンスの違いをもう少し学んでくれ
703 名前:デフォルトの名無しさん (オッペケ Sr97-w0Gz) mailto:sage [2017/03/18(土) 14:11:31.23 ID:2lr6MuOgr.net] なんだ、継承の意味を知らないんじゃなくて std::bindを見てECMAScriptのbindingと同じものだと勘違いしていただけか。 これでは話が噛み合うはずがない
704 名前:デフォルトの名無しさん (ワッチョイ 537b-gO1F) [2017/03/18(土) 14:14:40.36 ID:ux+WuUO90.net] >>687 新しい文法追加してa-> *func って書いたらaを参照キャプチャしてfuncを呼び出す関数オブジェクトを返すようにしてほしいらしいよ。
705 名前:デフォルトの名無しさん (ワンミングク MM5f-W3uL) mailto:sage [2017/03/18(土) 14:17:30.12 ID:TmvAgLdoM.net] >>689 関数を一級オブジェクトにしろという主張?? 別の言語でやれとしかいいようがないな…
706 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/18(土) 14:20:22.86 ID:waR+gchT0.net] >>681-682 > インスタンス構築 それはインスタンス構築ではなく、使う物だけとりあえず入れてるんだよ。 a を構築しているのではなく、 a.func の数式 k*x+a を使いたいから、 とりあえず a と k に値を入れて使っているだけ。 数式を間借りしているだけなんだ。 もっと a が複雑で、100個くらいメンバを持っているベクトル値だったとして、 calcも calc_0 〜 'calc_100 とかあったとして、そのうち1個だけ丁度いい数式があったら、それを借りる感じ。 このデタラメっぷりはC++にいると理解不能だが、JavaScriptに慣れるとC++が色々面倒で仕方ない。 そもそもテンプレートも型消去も最初からvarだとやらなくていいんだよ。 (その分デバッグが辛いが)
707 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/18(土) 14:24:47.73 ID:waR+gchT0.net] >>689 いやその文法はすでにC++0xにあるとの理解だが、これが間違いか? 既に>>663 にURL上げたが。 > メンバーを指すポインター演算子 .* および ->* は、特定のクラス・オブジェクトのメンバーを指すポインターをバインドする際に用いられます。
708 名前:デフォルトの名無しさん (ワンミングク MM5f-W3uL) mailto:sage [2017/03/18(土) 14:26:29.15 ID:TmvAgLdoM.net] >>691 > それはインスタンス構築ではなく、使う物だけとりあえず入れてるんだよ。 >とりあえず a と k に値を入れて使っているだけ。 >数式を間借りしているだけなんだ。 それをインスタンス構築っていうんだよ、覚えとけばか >もっと a が複雑で、100個くらいメンバを持っているベクトル値だったとして、 >calcも calc_0 〜 'calc_100 とかあったとして、そのうち1個だけ丁度いい数式があったら、それを借りる感じ。 そういう場合はお前の言うとりあえずだけを入れられるコンストラクタ作るんだよ まぁ普通の感性ならその部分はサブクラスとして切り出すけどね >このデタラメっぷりはC++にいると理解不能だが、JavaScriptに慣れるとC++が色々面倒で仕方ない。 >そもそもテンプレートも型消去も最初からvarだとやらなくていいんだよ。 面倒ならjsで書いとけばいいんじゃないですかね
709 名前:デフォルトの名無しさん (ワンミングク MM5f-W3uL) mailto:sage [2017/03/18(土) 14:27:43.20 ID:TmvAgLdoM.net] >>692 間違い
710 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/18(土) 14:43:08.69 ID:waR+gchT0.net] >>684 ちなみに何でそれ書けないんだ? std::function<...> f_bound = a.func; // (E) バインド済み std::function<...> f_not_bound = A::func; // (F) 未バインド、第1引数はthis で文法的に問題ないし、普通にこうだと思っていた。 ただし俺はC++でメンバポインタを使ったことはないから、 現在駄目なのなら何か理由があるのだろうけど、 逆にそうだと信じ切っており、 JavaScriptはこれができない=常にbindが必要なのでウザくて仕方なかった。例えば、 var func = someInstance.someMethod.bind(someInstance); と常に2回 someInstance と書く必要があり、これがウザイ。 ただC++も同じく糞なのか?
711 名前:デフォルトの名無しさん (ワンミングク MM5f-W3uL) mailto:sage [2017/03/18(土) 14:55:00.20 ID:TmvAgLdoM.net] >>695 classとインスタンスの違いがわかってないうちはマジで理解できないだろうからもう諦めろ JavaScriptのbind一通り調べたよ jsは関数型に依っててインスタンスって考え方がないんだな
712 名前:デフォルトの名無しさん (ワッチョイ a30e-BL3h) mailto:sage [2017/03/18(土) 15:03:41.03 ID:JpaAP8SC0.net] 最悪一部menberの参照だけ取られる表記と同じで、それがメンバ関数だとインスタンス全部が人質になるとか怖すぎ。
713 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/18(土) 15:44:12.23 ID:waR+gchT0.net] >>696 インスタンスとクラスの違いが分かってないのはお前だろ。 >>695 をJavaScriptで再記すると、 var a = new A(); var func_0 = a.func; // bindされない ← 直感的にはbind済みであって欲しい var func_1 = A.prototype.func; // bindされない ← これはOK で、JavaScriptは両方ともbindされないんだよ。 だから他言語から来た連中はbindを忘れてここでバグると言われている。 その「他言語」ってのは俺はてっきりC++だと思っていたから、695の理解になる。 ところがC++も同様に糞ならまあそれでよし。 改めて見ると、代入出来ないってことか?つまり、以下が出来ない。 std::function<...> f = a->*func; // bind済み std::function<...> f = a.*func; // bind済み なるほどC++も糞だな。ただ、実装自体は>>669 で出来るのだから、 何故これを出来ないようにしたのかは謎だが。
714 名前:デフォルトの名無しさん (ワッチョイ 838b-UnlH) mailto:sage [2017/03/18(土) 15:49:31.59 ID:YXP7lJmh0.net] JavaScript… あれはインスタンスしかないみたいな似非^2オブジェクト指向じゃん? あまりの酷さに批判が高まったのか、エッセンス6とかでprototypeキーワードが導入されたが それぐらいのもん ちなC++の話として、クロージャはあんま継承関係無い f.calc(x, 2)をfunc(x)の如く扱いたければfの所有でおk
715 名前:デフォルトの名無しさん (ワッチョイ 838b-UnlH) mailto:sage [2017/03/18(土) 15:55:28.34 ID:YXP7lJmh0.net] 個人的にはstd::bind(&F::calc, f, _1, 2)ですらF::calcの直接callに最適化されずに、 間接メモリアドレッシング後のcall止まりになるんではないかと危惧してゐる テンプレートを使える環境にありながら 関数へのポインタなど使うのは教育上によろしくない
716 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/18(土) 16:02:10.31 ID:waR+gchT0.net] なおC#ではあっさり書けることが判明した。 > class DelegateTest > { > static void Main() > { > Person p1 = new Person("鬼丸美輝"); > Person p2 = new Person("神無月めぐみ"); > > ShowMessage show = new ShowMessage(p1.ShowName); > show += new ShowMessage(p2.ShowName); > show += new ShowMessage(A); > show += new ShowMessage(B); > > show(); > } > > // 結果 > // 名前: 鬼丸美輝 > // 名前: 神無月めぐみ > // A が呼ばれました。 > // B が呼ばれました。 > ufcpp.net/study/csharp/sp_delegate.html
717 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/18(土) 16:02:29.43 ID:waR+gchT0.net] そしてC++でも出来そうなんだが、、、 > Human alice; > printf("Alice"); > (alice.*pf5)(); > > // おまけ > int Human::*x = &Human::age; > alice.age++; > printf("age = %d (%d)", alice.*x, &(alice.*x)); > qiita.com/Ted-HM/items/282785fcdcd06fb59642
718 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/18(土) 16:27:36.88 ID:waR+gchT0.net] >>699 > 似非^2オブジェクト指向じゃん? あれはクラスベースではなくプロトタイプベースだから。 それを無理矢理クラスベースとして使おうとするからおかしな事になる。 最初からプロトタイプベースとして使えば何も問題なく、 実際に表現出来る範囲もクラスベースよりも広いので、なかなか面白い。 > ちなC++の話として、クロージャはあんま継承関係無い JavaScriptでも継承とクロージャは全く関係ない。 > f.calc(x, 2)をfunc(x)の如く扱いたければfの所有でおk これはそうだと思う。 fがf_boundに変わっても手間は同じで、意味ねーというのが最初の主張。 >>700 > 個人的にはstd::bind(&F::calc, f, _1, 2)ですらF::calcの直接callに最適化されずに、 というかこれを期待するのがC++なのか? それはさすがに厳しいとは思うが、確かに無理ではないが。 > テンプレートを使える環境にありながら > 関数へのポインタなど使うのは教育上によろしくない これはどういう意味?さすがに今回の上記 > std::bind(&F::calc, f, _1, 2) をテンプレートで常に直接callするようには出来ないだろ。 というかテンプレートと関数ポインタの使う範囲は被らないと思うが。(代替出来ない)
719 名前:デフォルトの名無しさん (ワッチョイ 838b-UnlH) mailto:sage [2017/03/18(土) 16:35:15.55 ID:YXP7lJmh0.net] >> 個人的にはstd::bind(&F::calc, f, _1, 2)ですらF::calcの直接callに最適化されずに、 >というかこれを期待するのがC++なのか? >それはさすがに厳しいとは思うが、確かに無理ではないが。 できる F:calc()は仮想関数では無いし、 表記の例では&F:calc自体が(F::calc()と同じシグネチャを持つ別名の関数とかに)差し替えられはしないので 本質的には直接callとなるべきもの
720 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/18(土) 16:38:53.29 ID:waR+gchT0.net] ああ分かった。 >>702 はこちらの解釈間違い、これは出来ているわけではないね。 .* と ->* はあくまでその場で呼んでいるだけであって、 bind済みの関数を返してくれるわけではないのね。
721 名前:デフォルトの名無しさん (ワンミングク MM5f-W3uL) mailto:sage [2017/03/18(土) 16:42:00.60 ID:TmvAgLdoM.net] もういいよ jsスレでやれよ
722 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/18(土) 17:00:49.05 ID:waR+gchT0.net] >>704 > 本質的には直接callとなるべきもの それを言いだしたら全部だろ。そうなってないから色々問題なわけで。 ただこれに関してはスタックイメージを揃えればいいだけだから、やる気だけだね。 最初からスタックイメージを揃える呼び出しを用意してもいいし、 一旦>>669 の形式で2段階呼び出しにして、インラインにしてもいい。 (ただしインライン展開対象は外側関数なので従来最適化ルーチンは使えない) いずれにしても難しくはないよ。やる気だけの問題だね。
723 名前:デフォルトの名無しさん (ワッチョイ c353-PkJR) mailto:sage [2017/03/18(土) 17:01:39.49 ID:U4KC6daQ0.net] 知識がないのに何故語ろうとする
724 名前:デフォルトの名無しさん (ワッチョイ 838b-UnlH) mailto:sage [2017/03/18(土) 17:59:03.48 ID:YXP7lJmh0.net] >それを言いだしたら全部だろ。そうなってないから色々問題なわけで。 std::bind(&F::calc, f, _1, 2)という記述を見たコンパイラはポインタが関係するのでF::calc()を直接呼出しして良いものか迷うかもしれないが、 std::bind(<F::calcを表す関数オブジェクト>, f, _1, 2)なら std::bind()自体の書き方や関数オブジェクトの書き方がよほどアレでない限りはF::calc()直接呼出し相当のコードになる 全部一緒というなら一緒なんだろう藻前の中では(ry
725 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/18(土) 20:18:06.83 ID:waR+gchT0.net] >>709 いや結局何が言いたいんだ? 君:700「std::bind(&F::calc, f, _1, 2)は最適化されないかも…」 俺:703「それを期待するのは厳しいだろ」 君:704「いやできるし、そうなるべきだ」 俺:707「そりゃそうだが」 人間が見れば簡単に分かることが出来ないなんて!なんてのは全部だよ。 一般的にはポインタになった時点で最適化が難しくなる。 f->calc(x,k); // 直接呼び出し std::bind(&F::calc, f, _1, 2)(x); // 直接呼び出し std::function<...> f; // (G) f = std::bind(&F::calc, f, _1, 2); // (H) f(x); // 2段呼び出し // (I) f = std::bind(&F::calc, f, 2, _1); // (J) f(k); // 2段呼び出し // (K) C++では「戻り値と引数」が合ってたら良いんだろ? だったら(G)はいけるよな? この場合、fには(H),(J)とも可能なんだよ。 バインドされているのは第1引数でも第2引数でもいい。 ところがこれを実行する際、直接呼び出しに展開する為には、 (I)と(K)で呼び出し方法を変えなければならない。 スタック上の引数の位置が異なるからね。 そして一般的には(H)(J)はどこか遠いところで代入されており、 通常はその関数外から与えられる。 だから最適化は難しいんだよ。
726 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/18(土) 20:18:41.61 ID:waR+gchT0.net] ローカル関数内でfが分かりやすく代入されている場合は完全に最適化出来る。 同様の方法で外部から与えられた場合でも常に最適化する為には、 fに代入される可能性のあるポインタを全て精査する事が必要だが、一般的にこれは無理。 (書いた本人には何が入る可能性があるか簡単に列挙出来るが、 ソースコードから抽出するのはかなり無理) したがって、次案としては、 f自体に「第○引数を第△引数に入れ替え、第●引き数は▲で固定」という情報を持たせ、 対応することになる。(なおこの操作を別関数として行うのが「2段呼び出し」になる。) もっとも、C++のメンバポインタはintサイズでなくてもいいみたいなので、 この方法でも出来なくもないが、VC++ではやってないね。 > VC++で試したところ、普通は4、多重継承していれば8、仮想継承していれば12となりましたが、 > www7b.biglobe.ne.jp/~robe/cpphtml/html03/cpp03058.html これをやっていれば通常でも4では済まない。 多重で増えているのはポインタのずれを補正する分だね。 > https://www.microsoft.com/japan/msdn/vs_previous/visualc/techmat/feature/jangrayhood/
727 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/18(土) 20:19:09.95 ID:waR+gchT0.net] 分かるか? 完全に「直接呼び出し」にするには動的データとして「メンバ関数オブジェクト」みたいな物を作り、 それの展開ルーチンをインラインで埋め込まないといけないんだよ。 (サブルーチンで呼び出すと結局2段呼び出しになるだけ無駄) だったらそのままその「展開ルーチン」→「ターゲットメンバ関数」の2段呼び出しでもいいや、ってことになるだろ。 それがVC++でこの部分の直接呼び出し最適化をしていない理由だと思うよ。 多分さほど効果がないんだよ。(やる事自体は難しくない) 表面的な原因は、「第1引数がbindされた関数ポインタ」「第2引数がbindされた関数ポインタ」が 同じ型になってしまうことだよ。だからといって、これらが別型なのは言語として糞だろ。 明示的に分かりやすくその場で代入されている場合は、 これらを別扱いすればいいだけだから比較的楽に対応出来る。 だけど一旦ポインタとして受けられた場合、どれになるかは分からなくなるので無理になる。 それで、ポインタ自体にその情報を与えて動的モドキで対応するよりも、 単純に2段呼び出ししたほうがマシ、という判断が為された、ということだよ。VCでは。 ただ、2段呼び出しは「継承したクラス」を自分で書いた場合で、 std::bindってevalするわけではなくて、静的なライブラリ(=データしか作成出来ない)だよな? だったら内部的に上記「メンバ関数オブジェクト」方式になっている可能性が高く、 2段呼び出しで汎用ルーチンで展開=一番遅いパターンだと思うけどね。 まあここら辺はそっちの方が詳しい気がするが。 で、改めて聞くが、何が言いたいんだ? 俺はCコンパイラを作っているわけではないし、俺に文句言われても知らんがな。 結論としては、 > std::bind()自体の書き方や関数オブジェクトの書き方がよほどアレでない限りはF::calc()直接呼出し相当のコードになる は間違いだね。理由は上記、完全精査はかなり難しいからだ。 (もし出来てるのならスゲーとは思うけど)
728 名前:デフォルトの名無しさん (ワッチョイ 3fe5-eT6H) mailto:sage [2017/03/18(土) 20:25:58.81 ID:vEAnzxNk0.net] std::hashのconstexpr版って標準に入る予定とかないの?
729 名前:デフォルトの名無しさん (ワッチョイ 738b-UnlH) mailto:sage [2017/03/19(日) 00:13:07.69 ID:F98WB86R0.net] >>710-712 長文乙だがstd::bind()が(テンプレート関数なので)インライン展開されるということが何を含意し、 関数オブジェクトと組み合わせたときどういう効果があるかあんまお分かりではなさげ std::bind()内の第1引数への操作がインライン展開されるならば(そのようにstd::bind()自体が書かれているならば 第1引数の操作に関して >人間が見れば簡単に分かること は、 >コンパイラが見れば簡単に分かること と一致する(>>709 の「std::bind()自体の書き方(中略)がよほどアレでない限りは」がソレを指してゐる で、第1引数が関数オブジェクトでありかつF::calc()が仮想関数で無い限りは、F::calc()というシンボルのアドレスが コンパイル時に決まるから、直接呼出しのコードにできる 第1引数がポインタの場合はそうとは限らず、std::bind()の呼び出しの外もみてポインタが指すシンボルが一意であることまで 確認しないとコンパイラはF::calc(this, x, 2)というcallで済むところを(*p)(this, x, 2)的なコードにしかできない
730 名前:デフォルトの名無しさん (スプッッ Sddf-8YZg) mailto:sage [2017/03/19(日) 00:17:51.96 ID:UQylyHTkd.net] お前らのおすすめのデザインパターんおしてて
731 名前:デフォルトの名無しさん (ワッチョイ 738b-UnlH) mailto:sage [2017/03/19(日) 00:18:40.25 ID:F98WB86R0.net] 訂正 誤: F::calc()というシンボルのアドレスがコンパイル時に決まるから、直接呼出しのコードにできる 正: F::calc()というシンボルの呼び出しであることがコンパイル時に確定するから、直接呼出しのコードにできる
732 名前:デフォルトの名無しさん (オッペケ Sr97-w0Gz) mailto:sage [2017/03/19(日) 00:38:21.66 ID:rBaNXWYpr.net] >>715 とりあえずRAIIは使っとけ ナマポをnewする奴は殺害されても犯人に情状酌量の余地が残る
733 名前:デフォルトの名無しさん (ワンミングク MM5f-W3uL) mailto:sage [2017/03/19(日) 00:38:32.17 ID:Sogj9z7eM.net] >>715 expression template
734 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/19(日) 01:10:03.99 ID:7dJ8iAqk0.net] >>714 日本語で説明しようとしたのはまずかった。C++で書き直すと、以下。 ただしC++文法には詳しくないので、syntaxErrorは適宜脳内修正よろしく。 意味だけ見てくれ。ソースは>>666 から流用してる。 class F { int _a; public: F(const int a):_a(a) {} int calc(const int x, const int k) const { return k * x + _a; } }; int main() { const F f0(1); const F f1(2); std::function<...> f0_1 = std::bind(&F::calc, f0, _1, 3); // 第2引数を固定 std::function<...> f0_2 = std::bind(&F::calc, f1, 4, _1); // 第1引数を固定 std::function<...> f1_1 = std::bind(&F::calc, f1, _1, 5); // 第2引数を固定 call_sub(F0, f0_1, f0_2); call_sub(F1, f1_1, f0_1); } void call_sub(F& f, std::function<...> f1, std::function<...> f2){ f->func(1,2); // (L) 直接呼び出し f1(3); // (M) コンパイラによっては直接呼び出し、一般的には2段階呼び出し f2(4); // (N) 2段階呼び出し }
735 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/19(日) 01:10:33.50 ID:7dJ8iAqk0.net] (L)は必ず直接呼び出しになる。アセンブラなら push, push, push, call (M)はソース上を精査すれば同型呼び出ししかないことが分かるので 技術的には(L)と同程度まで最適化可能ではあるが、一般的には無理だと思う。 2段階呼び出し時は push, push, push, call, mov, jmp (N)は異なる形の呼び出しが与えられているので、 技術的に(L)と同じコスト(アセンブラ4命令程度)の直接呼び出しは不可能。 無理にcmpとかやるより普通に2段階呼び出しの方がいいと思う。 だからVCもそうしていると見ている。 それで、std::bindについては詳しい奴が以下見れば実装の見当が付くはずだが、 俺はC++用語に詳しくないので分からん。 ja.cppreference.com/w/cpp/utility/functional/bind 俺が実装するなら、ありがちなのをテンプレートで実装するが、 その場合はポインタサイズはsizeof(int)*2になる。 (メンバ関数へのポインタと、bind済みの値をstructで持つ=内部的な匿名クラスにするから) VCがなぜ4に出来るのかは分からん、というか計測間違いじゃないかと思う。 (バインド済みの値の分を入れてない)
736 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/19(日) 01:11:05.58 ID:7dJ8iAqk0.net] 俺が言いたかったのは、上記(L),(M),(N)ということ。 君の主張は、すべてbind時で確定して、上記(M)(N)も(L)と同じコストで呼べるという主張だと読める。 それは無理。 確かにアドレス自体は確定はするが、 引数をbindしているのだからスタックをその形にしてやらないといけない。 上記(N)の呼び出し、アセンブラ4命令ではどうやっても書けないだろ。 cmp使って書くくらいなら2段階呼び出しで6命令(2分岐)の方がマシ。 cmp使って無理に直接呼びにしたら、 そこに来る可能性のある呼び出し型を全部そこに書かなければならなくなる。 そしてx86はプレディケートを持ってないので、cmpで分岐しないといけない。(ARMは持っている) それって完全に本末転倒だろ。 それで、std::bindと関数オブジェクトをどう組み合わせたら、 (L),(M),(N)について上記通りアセンブラ4命令程度で呼び出せるのかよろしく。
737 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/19(日) 01:17:42.85 ID:7dJ8iAqk0.net] すまん、重要なところを間違えていたので訂正。 >>719 > std::function<...> f0_1 = std::bind(&F::calc, f0, _1, 3); // 第2引数を固定 > std::function<...> f0_2 = std::bind(&F::calc, f1, 4, _1); // 第1引数を固定 > std::function<...> f1_1 = std::bind(&F::calc, f1, _1, 5); // 第2引数を固定 の2つ目、インスタンスは f0 ね。 std::function<...> f0_2 = std::bind(&F::calc, f0, 4, _1); // 第1引数を固定, f0 ただ結局、変な引っかけみたいになっているだけで意味は同じかな? まあ訂正しとくけど。
738 名前:デフォルトの名無しさん (ワッチョイ bfcc-UNkP) mailto:sage [2017/03/19(日) 01:31:51.96 ID:i6MRGbY60.net] まだJAVAガイジ張り付いているのか…
739 名前:デフォルトの名無しさん (ワッチョイ 8330-PVeP) mailto:sage [2017/03/19(日) 01:41:06.04 ID:I9SbzQA70.net] あんだけ無能な醜態をさらしておいて ボクはレベルが高いけどちょっと知らなかっただけちょっと間違えただけで済んで まだ自分のいうことに説得力がある聞いてくれる人がいると思ってるところがもうね…
740 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/19(日) 01:44:23.31 ID:7dJ8iAqk0.net] bindの説明読む限り、やっぱこれかなり汎用に作っていて遅いと思うぞ。 ただ一般的にはそこが見えるほど使うことはないと思うが。 アセンブラ的には、 f->func(): 4命令程度(分岐1回) std::bind経由での呼び出し: 10-50命令程度か?(分岐2回以上) 内部オブジェクト作成方式: 6命令程度(分岐2回) じゃないかな。
741 名前:デフォルトの名無しさん (ワッチョイ 537b-gO1F) [2017/03/19(日) 01:49:16.54 ID:jcDR9uoj0.net] まぁ、別にスレ違いというわけでもないからいてもいいんじゃない?付き合いたい人が付き合えば。 俺はレスしないけど。
742 名前:デフォルトの名無しさん (ワッチョイ 537b-v8EU) mailto:sage [2017/03/19(日) 01:59:32.09 ID:jcDR9uoj0.net] と、言ったものの、我慢しきれないので撤回します。 >>725 https://godbolt.org/g/SFtHQt こうなる意味を考えて。 もう一つヒントあげるとstd::function<int()>で受けるとどうなるか見てみたらいいよ。
743 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/19(日) 02:14:29.60 ID:7dJ8iAqk0.net] 誰かと思えば>>678 か。 じゃあついでに言っておくと、以下だね。 callbacks.push_back([&]{a.func();}); // (O) クロージャ作成が無駄 callbacks.push_back(a->func)); // (P) この書き方は現在出来ないが、こっちの方がいい JavaScriptでは(O)は無駄だとされる。クロージャが余分にメモリを食うから。 クロージャ無しで書けるならその方がいい。コード領域も無駄だし。 これはC++も同じだし、C++の方が厳しいはずだが。 とはいえstd::bindの仕様が重すぎるのでこちらもイマイチだ。 C++ならどっちが重いかは微妙だね。 なおJavaScriptのbindは「前から順に固定される」だけの仕様なので、 固定した引数分のデータ領域しか各bindインスタンスには必要ない。 というかC++のbindが妙にリッチな仕様なのが謎だが。C++っぽくない。
744 名前:デフォルトの名無しさん (ワッチョイ 537b-gO1F) [2017/03/19(日) 02:17:00.87 ID:jcDR9uoj0.net] >>728 C++なら無駄ではない 終了
745 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/19(日) 02:19:33.17 ID:7dJ8iAqk0.net] >>727 俺には計算済みとしか見えないが、何か操作必要? -O3外せとかか? > fn(int): > lea eax, [rdi+rdi] > ret > bind(): > mov eax, 4 > ret > direct(): > mov eax, 4 > ret
746 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/19(日) 02:28:44.92 ID:7dJ8iAqk0.net] >>727 というかな、根本的に間違ってると思うぞ。 一般的に関数ポインタを使う場合、それは外部から与えられるんだよ。 自分の内部で作って使うって事はない。 (ここでは単純なソースで議論するからそうなるだけで、一般的にはそうではない。 つか、それじゃ関数ポインタの意味がないし) 典型的にはcallbackだよ。外部から与えないと全く意味無いだろ。 で、その場合は当然この手の事前計算とかでの最適化は出来ないんだよ。
747 名前:デフォルトの名無しさん (ワッチョイ 537b-v8EU) mailto:sage [2017/03/19(日) 02:33:33.53 ID:jcDR9uoj0.net] >>731 一時一句同じじゃないと理解できない人だったか。 https://godbolt.org/g/o73pz4 これで理解できますか?
748 名前:デフォルトの名無しさん (ワッチョイ f35b-tpgq) mailto:sage [2017/03/19(日) 02:51:38.54 ID:7dJ8iAqk0.net] >>732 あーお前がアホだということはよく分かったわ。 まともに議論する気なら、お互いが見ているものが同一であることを確認しないといけない。 >>727 を見たらアホかと思うのは道理だろ。 そして>>732 もアホかと思うよ。関数内部で何を作ってもそれは最適化されるよ。 それは一時変数を除去すればいいだけなのだから。 そうではなくて、例えば以下にしないといけない。 int main(){ auto f = std::bind(&something::func,ptr); bind(f); } int bind(std::function<...> f){ return f(); // bind済みのfを呼ぶコストをここで計測する } 再度言うが、関数ポインタは外部から与えないと意味無いんだよ。
749 名前: てかお前ら実は全く関数ポインタ使ってないだろ。 だから使い方自体を知らないんだよ。 これで、bind/関数オブジェクト/クロージャで呼び出しコストを比べてみなよ。 当たり前だが上記だとbind呼んで終わりになるけど、 もちろんその先のターゲット(something::func)が呼ばれるまで見るんだよ。 つまりstd::bind内部のコードもね。それが呼び出しコストなんだから。 それで、あらかじめ計算済みとかいうアホなオチはマジで止めてくれ。 一般的にポインタを与えた場合、それが無理なことくらい分かるだろ。 [] [ここ壊れてます]
750 名前:デフォルトの名無しさん (ワッチョイ 537b-v8EU) [2017/03/19(日) 03:14:07.27 ID:jcDR9uoj0.net] >>733 注文の多いやつだなぁ。 https://godbolt.org/g/R1ljMl 関数ポインタを外から渡すようにかえてやったぞ。 自分で言ってることをC++で書く能力ぐらいあるよね? 次から自分で書けよ。 std::bindに余分なコストなんてない。std::functionの方にある。 ヒントあげたのに全く考えようとしなかったのかな?
751 名前:デフォルトの名無しさん (ワッチョイ 537b-v8EU) mailto:sage [2017/03/19(日) 03:24:22.16 ID:jcDR9uoj0.net] >>733 なぜか一時変数だから最適化できると信じてるみたいだけど、そう思うなら int std_function(something* ptr,fn_ptr_type fptr){ std::function<int()> f = std::bind(fptr,ptr); return f(); } と書いてみればいい。 >そして>>732 もアホかと思うよ。関数内部で何を作ってもそれは最適化されるよ。 >それは一時変数を除去すればいいだけなのだから。 がバカな発言だったと理解できると思うから。
752 名前:デフォルトの名無しさん (ワッチョイ 0f59-Rjy3) mailto:sage [2017/03/19(日) 03:38:13.98 ID:xwQyhAst0.net] ああ、Javaだと〜とか言ってた人か