1 名前:v(^・^)v [2007/09/26(水) 03:41:13 ] C++に関する質問やら話題やらはこちらへどうぞ。 ただし質問の前にはFAQに一通り目を通してください。 IDE (VC++など)などの使い方の質問はその開発環境のスレに お願いします。 テンプレその他 >>2-15 付近参照 前スレ(実質 part57) C++相談室 part56 pc11.2ch.net/test/read.cgi/tech/1185377587/
16 名前:デフォルトの名無しさん mailto:sage [2007/09/26(水) 11:17:02 ] 地鎮祭が済んだな乙
17 名前:デフォルトの名無しさん mailto:sage [2007/09/26(水) 11:35:06 ] そこまでがテンプレだからな。
18 名前:デフォルトの名無しさん mailto:sage [2007/09/26(水) 12:00:46 ] stlとかboost使いまくったら通常は1M程度で住むものが 10M超えたりするんでしょうか?
19 名前:デフォルトの名無しさん mailto:sage [2007/09/26(水) 12:07:37 ] 「通常」の定義がわからん
20 名前:デフォルトの名無しさん mailto:sage [2007/09/26(水) 12:15:08 ] それでは、よくある「クラスと継承が使えるbetter Cとして書いたC++のコード」を「通常」だと想定して答えて下さい 今作ってるものがboostをヴァリヴァリに使っているので それと比較すればどれぐらいバイナリサイズは肥大するのかがちょっと気になります
21 名前:デフォルトの名無しさん mailto:sage [2007/09/26(水) 12:25:32 ] バイナリサイズよりコンパイル時間の肥大が気になる。
22 名前:デフォルトの名無しさん mailto:sage [2007/09/26(水) 12:28:21 ] 通常、増える場合と減る場合、そして変わらない場合があります。
23 名前:デフォルトの名無しさん mailto:sage [2007/09/26(水) 12:33:21 ] 全スレ >827 名前:デフォルトの名無しさん 投稿日:2007/09/22(土) 23:20:47 >emacsでc++開発をするときの環境に関するサイトってないでしょうか? flymake d.hatena.ne.jp/pyopyopyo/20070715/p1
24 名前:デフォルトの名無しさん mailto:sage [2007/09/26(水) 19:15:43 ] >>22 何そのトートロジー
25 名前:デフォルトの名無しさん [2007/09/26(水) 20:27:10 ] int data[10] ={10,20,30,40,50,60,70,80,-999} このようなint配列があります 配列の内容を実行結果のように表示するプログラムを作りなさい -999になれば処理を終了します ポインタを固定して表示させる処理とポインタを変化させて表示させる処理の2つ作成しなさい この内容がわからないので教えて下さいお願い致します
26 名前:デフォルトの名無しさん mailto:sage [2007/09/26(水) 20:31:33 ] なんだマルチか
27 名前:デフォルトの名無しさん mailto:sage [2007/09/26(水) 21:52:11 ] スレ建て乙
28 名前:デフォルトの名無しさん mailto:sage [2007/09/27(木) 00:22:22 ] >>1 おつかれ >>10 GJ! 有用なサイトを手っ取り早く見つける方法... それはテンプレを見ることだ。
29 名前:デフォルトの名無しさん [2007/09/27(木) 00:22:33 ] int *p = data; int i = 0; while(*p++ != 999) std::cout << *p << std::endl; while(*(p + i) != 999) std::cout << *(p + i) << std::endl;
30 名前:デフォルトの名無しさん mailto:sage [2007/09/27(木) 01:55:53 ] 999ではなく-999 2つ目のループ前にpを初期化しないといけない
31 名前:デフォルトの名無しさん [2007/09/27(木) 09:48:49 ] C++で書かれた、正規表現処理クラスみたいなものってありませんか?
32 名前:デフォルトの名無しさん mailto:sage [2007/09/27(木) 10:00:16 ] boost/random.hpp
33 名前:デフォルトの名無しさん mailto:sage [2007/09/27(木) 10:00:50 ] ミスった。 boost/regex.hpp
34 名前:デフォルトの名無しさん mailto:sage [2007/09/27(木) 10:25:06 ] !?
35 名前:デフォルトの名無しさん mailto:sage [2007/09/27(木) 10:57:19 ] double a[3000][3000]; て定義すると蹴られるんだけど、なんでかわかる人いますか?
36 名前:デフォルトの名無しさん mailto:sage [2007/09/27(木) 11:09:59 ] 環境は?
37 名前:デフォルトの名無しさん [2007/09/27(木) 11:14:19 ] VC6のSDKでウィンドウを持ったクラスの継承がしたいです。 Hoge1クラス:メインウィンドウになるクラス Hoge2クラス:継承元となるウィンドウを持ったクラス Hoge3クラス:Hoge2クラスを継承したクラスでHoge1ウィンドウのボタンを押したときに表示されるウィンドウを持ったクラス Hoge2クラスはWinProcをstaticでクラス内に入れています。クラスの登録やウィンドウを生成する関数はprivateとして存在します。 Hoge3クラスも同じような構成です。 で、Hoge3クラスで不用なメッセージ処理はHoge2のウィンドウクラスに回してやりたいのですが、 その方法がいまいちわかりません。手順・・がいまいちです。 Hoge3クラスの登録をする前に、Hoge2クラスのウィンドウを登録する必要があると思い、 WNDCLASSEXを使ってウィンドウの登録をする?と思いきや、横取りするHoge2にあるプロシージャとかも指定しないといけないわけですよね? でもこの段階だと、Hoge2クラスの存在すら誰も知らないわけで・・・この辺りがよくわかりません。 ボタンのスーパークラス化と同じようなイメージでいるのですが、ボタンの場合は ウィンドウズが予めその存在を認識しているからGetClassInfoExを使って情報を取得する ことができますが、自作ウィンドウクラスの場合はそれができなくて・・・
38 名前:デフォルトの名無しさん mailto:sage [2007/09/27(木) 11:16:33 ] >>35 俺のエスパー能力が、環境がx86なPCであると言っている。 さらに、かなりの確率でWindowsであると言っている。 さらに、俺のエスパー能力はこう言っている。 コンパイラ「スタック足りねーよボケッ!」 ttp://www.google.com/search?&q=8+*+3000+*+3000+byte
39 名前:デフォルトの名無しさん mailto:sage [2007/09/27(木) 12:15:58 ] >>35 配列が大きすぎてスタック領域が足りてない。と思われる。 巨大な配列を宣言するときは new するか static にするべき
40 名前:デフォルトの名無しさん mailto:sage [2007/09/27(木) 12:28:43 ] 俺の環境ではgcc 3.4やvc2005でも文句言われないんだけど… そのかわり実行時にスタックオーバーフロー そういうオプションでもあるの?
41 名前:デフォルトの名無しさん mailto:sage [2007/09/27(木) 12:34:20 ] >>35 誰に蹴られるって?
42 名前:デフォルトの名無しさん mailto:sage [2007/09/27(木) 12:38:23 ] >>41 金色のファルコ
43 名前:デフォルトの名無しさん mailto:sage [2007/09/27(木) 21:58:29 ] >>39 必要ないのに無駄にnewなんか使うなよ。 どうしてもSTLは使いこなせないってことなら話は別だが。
44 名前:デフォルトの名無しさん mailto:sage [2007/09/27(木) 21:59:28 ] >>37 1. 静的メンバ関数となっているHoge2のウィンドウプロシージャから 仮想関数にしたウィンドウプロシージャを呼ぶようにして、 Hoge3でそれをオーバーライドする。 Hoge3では新たなウィンドウクラスを登録しない。 2. Hoge2のWinProcをprotectedにして、Hoge3のウィンドウプロシージャでは、 DefWindowProcの代わりにHoge2::WinProcを呼ぶようにする。 Hoge3では新たなウィンドウクラスを登録する必要がある。 俺は1をよくやる。2こそはスーパークラス化だな。 ウィンドウプロシージャの仮想関数化はここが参考になる。 techtips.belution.com/ja/vc/0009/ www.google.com/search?q=cache:http://techtips.belution.com/ja/vc/0009/
45 名前:デフォルトの名無しさん mailto:sage [2007/09/28(金) 00:17:35 ] >>43 スタックじゃサイズ足らないって理由だけでnewすんのもSTL使うのも大差ないだろ
46 名前:37 [2007/09/28(金) 01:30:59 ] >>44 そこは何度も見てるのですが・・・。そこに書いてあるクラスは、 それを継承させると簡単にサブクラス化できたり元に戻せたりする クラスってことですよね?
47 名前:デフォルトの名無しさん mailto:sage [2007/09/28(金) 02:05:57 ] >>37 >で、Hoge3クラスで不用なメッセージ処理はHoge2のウィンドウクラスに回してやりたいのですが、 >その方法がいまいちわかりません。手順・・がいまいちです。 Hoge3 クラスは Hoge2 クラスを継承してるんだから、ただ単に継承元クラスのメンバ関数を呼ぶだけでいいのでは ムダに難しいこと考えてない? Windows に登録するウィンドウクラスと C++ のクラスが一致してる必要はないよ C++ のクラスを継承してるからってウィンドウクラスをスーパークラス化したりサブクラス化したりする必要はない
48 名前:デフォルトの名無しさん mailto:sage [2007/09/28(金) 07:38:08 ] インナークラスっておまいら普通に使ってる?
49 名前:デフォルトの名無しさん mailto:sage [2007/09/28(金) 08:10:15 ] pimplの形でなら使ってるよ
50 名前:デフォルトの名無しさん mailto:sage [2007/09/28(金) 09:32:02 ] >>45 大差なくはない。vector使え。 例外安全な上に組込配列よりずっと便利だ。
51 名前:デフォルトの名無しさん mailto:sage [2007/09/28(金) 10:11:22 ] 2 4 16 256 65536 4294967296 * sizeof(double) = 8589934592b = 8192MB
52 名前:デフォルトの名無しさん mailto:sage [2007/09/28(金) 10:15:48 ] そこまでいったら流石にメモリマップドファイル使う
53 名前:37 [2007/09/28(金) 10:45:46 ] >>47 「ウィンドウ作成データとして、CWinBase クラスの派生クラス CxxxWnd オブジェクトを指定することを忘れないで下さい。」 が、何を指しているのかわからないです。どこにCxxxWnd オブジェクトを指定するのでしょう?
54 名前:37 [2007/09/28(金) 10:50:39 ] WNDCLASSEXを登録するとき、サンプルではBaseWnd::WindowMapProcを指定 しろとあるけど、指定するものを自分自身のWinProcを指定してやり Attachを呼べばいいのかな?
55 名前:デフォルトの名無しさん mailto:sage [2007/09/28(金) 11:00:24 ] >>53 それは、CreateWindowExの最後の引数。 CxxxWnd wnd; CreateWindowEx(..., &wnd); こういう感じ。CreateWindow(Ex)の引数は WM_CREATEまたはWM_NCCRAETEでCRATESTRUCTとして全て参照できる。 いつもこうしなければならないだから、 CreateWindowExもクラスのメンバにしてこの処理はしばしば隠蔽される。 そろそろスレ違いが近付いているぞ。
56 名前:37 [2007/09/28(金) 11:29:40 ] >>55 今そこ調べてました・・・ ttp://nomina.petit-archives.mydns.jp/tests/old/gecko012/nmnConsoleControl.cpp ttp://www7a.biglobe.ne.jp/~lshen/EternalWindows/WinBase/Window/Window08.html >>そろそろスレ違いが近付いているぞ。 もうすこし付き合ってください・・ その最後の引数に&wndを渡して自身のメンバ変数や関数にアクセス する場合、が微妙です。 WM_CREATEで LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam というところはOKです。ここから自分のメンバにアクセスする方法が いまいちです。
57 名前:デフォルトの名無しさん mailto:sage [2007/09/28(金) 11:33:18 ] 死ね
58 名前:37 [2007/09/28(金) 11:33:38 ] static Hoge3* pWnd = NULL; pWnd = (Hoge3*)(((CREATESTRUCT*)lp)->lpCreateParams); こんな感じか?な?
59 名前:デフォルトの名無しさん mailto:sage [2007/09/28(金) 11:36:24 ] CxxxWnd *wnd = (CxxxWnd*)lpcs->lpCreateParams;
60 名前:37 [2007/09/28(金) 11:37:44 ] >>55 できますた。ありがとうございます! あとは54なんですが・・・これがまた・・・orz
61 名前:デフォルトの名無しさん mailto:sage [2007/09/28(金) 11:38:16 ] 死ね
62 名前:デフォルトの名無しさん mailto:sage [2007/09/28(金) 11:42:22 ] >>60 Win32API質問箱 Build57 pc11.2ch.net/test/read.cgi/tech/1189255282/
63 名前:デフォルトの名無しさん mailto:sage [2007/09/28(金) 12:11:35 ] >>58 そこでstaticはやめとけ。 >>60 Hoge2::WinProcに相当するのが、44の指したページで言うCWndBase::WindowMapProc。
64 名前:37 [2007/09/28(金) 12:38:27 ] class Hoge:public CWndBase public: BOOL InitInstance( HINSTANCE hInstance ); private: //オーバーライドしたWndProc static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); }; 使うとき、 Hoge hoge; hoge.InitInstance(hInstance); InitInstanceの中ではウィンドウの登録、作成をする WNDCLASSEX wcex; : wcex.lpfnWndProc = (WNDPROC)BaseWnd::WindowMapProc;//WndProc; : RegisterClassEx(&wcex); で、CreateWindowする。最後の引数はthisを渡す。 こうすると、メッセージは、まずWindowMapProcで処理されて、 BaseWndのWndProcへ飛んできます。が、オーバーライドした自分のWndProcには飛んでこない です。CreateWindow後のAttachとか呼んでみたのですが、変わらずです。 なんか、おしい気がするのですが、ぜんぜんですかね?
65 名前:デフォルトの名無しさん mailto:sage [2007/09/28(金) 12:43:20 ] なぜ static が付いてる? それでオーバーライドになってると思ってるのか?
66 名前:デフォルトの名無しさん mailto:sage [2007/09/28(金) 12:48:32 ] >>64 44のページを良く見ろ。 WindowMapProcはstaticで、WndProcはvirtualだ。 静的メンバ関数で多態的なオーバーライドは不可能だ。
67 名前:デフォルトの名無しさん mailto:sage [2007/09/28(金) 12:49:18 ] お前らの優しさに嫉妬
68 名前:37 [2007/09/28(金) 13:29:59 ] あ、static付いてる。コールバックはstatic付けることで解決、なんての ばかり気にしてたので、普通につけちゃいました。 で、取ったらコンパイラ エラー C2555が出て、「そんなの聞いてませんが何か?」 とか思いつつ、調べること数分、どうにかメッセージを受信するとこまで できたようです。 今は、慣れてないのにいろんなことやってしまった(気でいる)ので、 これから1つ1つ整理して、ちゃんとしたものを作っていきます。 みなさまありがとうございました。
69 名前:デフォルトの名無しさん mailto:sage [2007/09/28(金) 14:22:21 ] やれやれ ┐(´ー`)┌
70 名前:デフォルトの名無しさん mailto:sage [2007/09/28(金) 14:33:43 ] でさ、なんでこの話題がC++スレで?
71 名前:デフォルトの名無しさん mailto:sage [2007/09/28(金) 15:26:42 ] 相手する低脳がいるから
72 名前:デフォルトの名無しさん [2007/09/29(土) 08:31:08 ] class A{ int a[10]; public: }
73 名前:デフォルトの名無しさん [2007/09/29(土) 08:34:44 ] 途中で書いてしまいました失礼しました class A{ int a[10]; public: int *get_a(){return a;} } int main(){ int *p; p = get_a(); for(int i = 0; i < 10; i++){ p[i] = ... ... = p[i]; } return 0; } このようなコードってカプセル化を壊してますか?
74 名前:デフォルトの名無しさん mailto:sage [2007/09/29(土) 08:40:45 ] >>73 うん。少し。
75 名前:73 [2007/09/29(土) 08:45:15 ] やはり配列のポインタを返すというのはまずいのでしょうか?
76 名前:デフォルトの名無しさん mailto:sage [2007/09/29(土) 08:48:46 ] >>75 うん。少し。
77 名前:デフォルトの名無しさん mailto:sage [2007/09/29(土) 10:23:23 ] >>78 うん。少し。
78 名前:デフォルトの名無しさん mailto:sage [2007/09/29(土) 12:03:52 ] やはり>>77 さんは早漏なのでしょうか?
79 名前:デフォルトの名無しさん mailto:sage [2007/09/29(土) 12:37:28 ] 早漏は経験をつめば治ります。めげずに頑張りましょう。
80 名前:デフォルトの名無しさん mailto:sage [2007/09/29(土) 17:31:27 ] こんな感じにしちゃえば? int get_a( int i ){return a[i];}
81 名前:デフォルトの名無しさん mailto:sage [2007/09/29(土) 21:08:11 ] 代入は?
82 名前:デフォルトの名無しさん mailto:sage [2007/09/29(土) 21:12:06 ] >>81 int& get_a(int i) { return a[i]; } int get_a(int i) const { return a[i]; }
83 名前:デフォルトの名無しさん mailto:sage [2007/09/29(土) 21:22:13 ] effective C++読めよー。
84 名前:デフォルトの名無しさん mailto:sage [2007/09/29(土) 21:44:16 ] っていうか言語以前の問題だろ。 っっていうか全部ネタだろ。
85 名前:デフォルトの名無しさん mailto:sage [2007/09/29(土) 23:56:29 ] なんで誰も内部ハンドルを返すのは云々って言ってあげないのか
86 名前:デフォルトの名無しさん mailto:sage [2007/09/29(土) 23:58:29 ] >>85 流れ嫁よ
87 名前:デフォルトの名無しさん mailto:sage [2007/09/30(日) 08:55:39 ] hoge.hの中で class hoge { public: virtual double CalcF1(Double_t r) const throw(std::exception); } hoge.cxxの中で double hoge::CalcdF1dr(Double_t r) const throw(std::exception) { } としてるんだけど、g++でcompileしようとすると src/hoge.cxx: In member function 'virtual double hoge::CalcdF1dr(Double_t) const': src/hoge.cxx:87: error: expected primary-expression before ';' token と怒られます。どこが書き方間違ってるんでしょうか。
88 名前:デフォルトの名無しさん mailto:sage [2007/09/30(日) 08:56:33 ] あ、ごめん。 class hoge { public: virtual double CalcdF1dr(Double_t r) const throw(std::exception); } でした。
89 名前:デフォルトの名無しさん mailto:sage [2007/09/30(日) 08:57:57 ] あ、ごめん。勘違い。 スルーして下さい。
90 名前:デフォルトの名無しさん mailto:sage [2007/09/30(日) 18:33:43 ] VC2003で作られた 静的なlibは、 VC2005でリンクすることは不可能なんですか?
91 名前:デフォルトの名無しさん [2007/09/30(日) 20:19:13 ] クラスの内側で定義したクラステンプレートを特殊化する、 class X { template<typename T> class Y {}; template<> class Y<int> {}; }; のようなコードは、VC++(2003/2005)ではコンパイルできますが、g++3/4では error: explicit specialization in non-namespace scope ‘class X’ というエラー になってしまいます。 Y<int>をXの中ではなく、名前空間スコープで template<> class X::Y<int> {}; と書けばg++でもVC++でも問題なく特殊化できることは知っているのですが、 なんとかg++で、特殊化されたクラスの定義をXの中に書く方法はないでしょうか? Y<T>とY<int>の定義が離れた場所にあると、コードが読みにくいと思うのです。 boost(特にmpl)の使用は歓迎です。 よろしくおねがいします。
92 名前:デフォルトの名無しさん mailto:sage [2007/09/30(日) 20:27:59 ] >>89 クラス末尾にセミコロンがありませんでした。ごめんなさい。 とちゃんと書こうYO!
93 名前:デフォルトの名無しさん mailto:sage [2007/09/30(日) 20:42:48 ] >>91 定義位置を近づけたいなら、両方クラス外に書けばいいんじゃね?
94 名前:91 [2007/09/30(日) 20:45:33 ] >>93 ああ、たしかにそうですね。他に案がなければそうしたいとおもいます。 ただ、Y<T>とY<int>を両方クラス内に書けると、宣言と定義の位置も離れない(定義だけになる)ので、 より読みやすいと思っています。 というわけで、引き続きお願いします。
95 名前:デフォルトの名無しさん mailto:sage [2007/09/30(日) 20:54:22 ] >>91 規格ではネストされたクラス内での明示的特殊化は禁止されているけど 部分特殊化はOKなので、 class X { template <typename T, class U = void> class Y {}; template <typename T> class Y< T , typename boost::enable_if< typename boost::is_same< T, int> > > {}; }; のようにenable_ifとis_sameを使って書くといいっぽい(初心者スレから一部拝借w) VCでコンパイル可能なのはmsの独自拡張でgccの方が正しいとのこと
96 名前:91 [2007/09/30(日) 20:57:38 ] なお、メンバ関数テンプレートで同様のエラーをくらう件については (下記の2行めがエラーになる)、 class X { template<typename T> void foo(T x) {} template<> void foo<int>(int x) {} // error }; 下記方法でごまかしています。 #include <boost/type.hpp> class X { void foo_(int x, boost::type<int>) { /* specialized */ } template<typename T> void foo_(T x, ...) {} public: template<typename T> void foo(T x) { foo_(x, boost::type<T>()) ;} };
97 名前:91 mailto:sage [2007/09/30(日) 20:59:12 ] >>95 部分特殊化はOKだったんですか。気づきませんでした。 早速試してみます。どうもありがとう〜!!
98 名前:デフォルトの名無しさん mailto:sage [2007/09/30(日) 21:00:46 ] >>91 私はC++初心者ですが、>>93 さんと同意見です。 >>95 さんの言うようにgccの方が正しい(つまり規格どおりということですよね)ならば、 なおさらそう思います。 それに、Xクラスの定義を見たいときには、むしろYは外にあった方が見やすいのではないでしょうか?
99 名前:デフォルトの名無しさん mailto:sage [2007/09/30(日) 21:06:58 ] ちなみに関数テンプレでもこの手は使えるようだ この手法も名前があったと思うけど思い出せない 使うなら適当にローカルなメタ関数を専用の名前空間に自作して階層を浅くする工夫が必要だね 使ってればわかるけど、凄く見にくくなるから
100 名前:デフォルトの名無しさん mailto:sage [2007/09/30(日) 21:10:12 ] あ、::type付けわすれた…
101 名前:デフォルトの名無しさん mailto:sage [2007/09/30(日) 21:43:54 ] 読み易くするのが目的で読みにくくなる手法を選ぶか。 >>99 名前があるならソレをコメントに書いておけば良いかも。
102 名前:デフォルトの名無しさん mailto:sage [2007/09/30(日) 22:00:44 ] >>98 >>101 読みやすいかどうかは読み手にもよるし、あまり>>91 や>>94 はよい聞きかたではなかったですね。 C++のコードを自動生成するツール(自作)の都合でX内に定義を書けると嬉しい、というのが実際の事情です。
103 名前:91 mailto:sage [2007/09/30(日) 22:32:03 ] 102は91です。 >>99 concept-controlled polymorphism ですか?
104 名前:デフォルトの名無しさん [2007/09/30(日) 23:06:47 ] >>100 > あ、::type付けわすれた… 検索エンジン経由で来るひとのために、一応訂正版貼っときますね。 #include <cstdio> #include <boost/utility/enable_if.hpp> #include <boost/type_traits/is_same.hpp> struct X { template<typename T, typename U = void> struct Y { Y() { std::printf("genecic\n"); } }; template<typename T> struct Y <T, typename boost::enable_if<boost::is_same<T, int> >::type> { Y() { std::printf("specialized for int\n"); } }; }; class Z {}; int main() { X::Y<Z> a; X::Y<int> b; X::Y<float> c; } 実行結果は、 genecic specialized for int genecic です。
105 名前:91=104 mailto:sage [2007/09/30(日) 23:31:30 ] boostが使えない場合は、VC++2003/2005/g++対応だけ考えるならこんな感じでしょうか。 #include <cstdio> namespace b00st { template <bool B, class T = void> struct enable_if_c { typedef T type; }; template <class T> struct enable_if_c<false, T> { /* NO TYPEDEF! */ }; template <class Cond, class T = void> struct enable_if : public enable_if_c<Cond::value, T> {}; template<bool b> struct bool_ { static const bool value = b; }; template<typename T, typename U> struct is_same : bool_<false> {}; template<typename T> struct is_same<T, T> : bool_<true> {}; } using namespace b00st; struct X { template<typename T, typename U = void> struct Y { Y() { std::printf("genecic\n"); } }; template<typename T> struct Y<T, typename enable_if<is_same<T, int> >::type> { Y() { std::printf("specialized for int\n"); } }; }; そろそろウザいとおもうので、これで打ち止めにします。ありがとうございました。
106 名前:デフォルトの名無しさん mailto:sage [2007/09/30(日) 23:40:10 ] このtemplate感、実に小気味良い 久しぶりにC++スレを実感した
107 名前:デフォルトの名無しさん mailto:sage [2007/10/01(月) 00:01:02 ] キモ
108 名前:デフォルトの名無しさん mailto:sage [2007/10/01(月) 00:04:13 ] 小気味良いのは確かだけど、言葉遣いが丁寧すぎてちょっと痒い、というのが俺の感想。 うん、俺の感想なんかどーだっていいってのは承知。
109 名前:デフォルトの名無しさん [2007/10/01(月) 02:02:08 ] >>99 enable_ifの関数テンプレへの適用で質問。ある条件で2つの関数を呼びわけたいときは、こんな感じにすればいいみたいだけど、 template<typename T> static void foo(T t, typename boost::disable_if<boost::is_same<T,int> >::type* = 0) { } template<typename T> static void foo(T t, typename boost::enable_if<boost::is_same<T,int> >::type* = 0) { // intへの特殊化版 } 3つ以上を呼びわけるにはどうすれば? たとえば、 template<int V> static void boo(typename boost::enable_if_c<V == 0>::type* = 0) { } template<int V> static void boo(typename boost::enable_if_c<V == 1>::type* = 0) { } template<int V> static void boo(typename boost::disable_if_c<V == 0 || V == 1>::type* = 0) { // default } とかだと、default caseな関数の引数が大変なことになってしまうような。 boostスレのほうがいいのかな。。
110 名前:デフォルトの名無しさん mailto:sage [2007/10/01(月) 02:51:44 ] 複雑な場合はmplの出番になるんじゃないかな mpl::if_< ..., mpl::if_< ..., > >::type::call();
111 名前:109 [2007/10/01(月) 03:23:49 ] >>110 すみません、それはどこに書くコードなんでしょうか? call() とは一体。。
112 名前:109 [2007/10/01(月) 03:28:24 ] >>110 が理解できず、独自に考察を進め中。 template<int V> static void boo(typename boost::enable_if_c<V == 0>::type* = 0) {} は、 template<int V> static void boo(typename boost::enable_if< boost::is_same< boost::mpl::int_<V>, boost::mpl::int_<0> > >::type* = 0) {} であり、さらに template<int V> static void boo(typename boost::enable_if< typename boost::mpl::lambda< boost::is_same< boost::mpl::_1, boost::mpl::int_<0> > >::type::apply<boost::mpl::int_<V> >::type >::type* = 0) {} だから、この数値0-Nでlambdaしたのをmpl::listで抱えて、特殊化版はlistのat<i>したのでenable_ifして、default版はこれらをandでfoldしたのにdisable_ifすればいいと思うんだぜ? ・・・絶対方向が間違ってる。
113 名前:デフォルトの名無しさん mailto:sage [2007/10/01(月) 03:37:53 ] いや、単に、mpl::if_で関数を実装したクラスを選んで呼び出す boost/smart_cast.hppが参考になるかも
114 名前:デフォルトの名無しさん [2007/10/01(月) 03:44:43 ] >>113 私は、単に boo(0); boo(1); boo(2); とだけ書くと、呼び先の関数がコンパイル時に決まるようにしたいと 思っているんですが、>>110 は、このbooを *呼ぶ側* をif_で工夫しろということ? まぁ、boo()でif_を使って、適切なboo_()を呼ぶようにしてもいいのかもしれませんが、 委譲してしまうとタグディスパッチと大差ないようにも思うし。。 なんか勘違いしてたらすんません。smart_castは早速見てみます。
115 名前:デフォルトの名無しさん mailto:sage [2007/10/01(月) 04:37:09 ] どうしてもenable_ifを使いたいなら 複雑な条件を書かずに済ますことは不可能だと思う
116 名前:109 [2007/10/01(月) 05:41:56 ] >>115 enable_ifが使いたいわけでは無くて、 1.メンバ関数テンプレートの特殊化(相当のこと - オーバーロードでもいい)を行いたい 2.特殊化の定義は、クラス内に書きたい (>>91 と同じく, 見た目の問題で) 3.メンバ関数を呼ぶ側はあまり難しいことを考えたくない 4.タグディスパッチのような別関数への処理の委譲は、できれば避けたい (これも見た目の問題で) という条件で、Pという場合と!Pという場合の処理の振り分けだったら、 enable_ifを使ったオーバーロードでOKとわかった(>>109 )が、P, Q, (!P && !Q) の3関数に振り分けたい場合にこの4条件を満たすようなのないですかね? というのが質問です。ちゃんと書かずにすみません。コンパイラはgccです。