1 名前:デフォルトの名無しさん [2009/07/18(土) 02:54:58 ] C++に関する質問やら話題やらはこちらへどうぞ。 ただし質問の前にはFAQに一通り目を通してください。 IDE (VC++など)などの使い方の質問はその開発環境のスレに お願いします。 前スレ C++相談室 part70 pc12.2ch.net/test/read.cgi/tech/1244942050/l50
369 名前:デフォルトの名無しさん mailto:sage [2009/08/09(日) 21:58:44 ] >>367 この手の場面に相当するような「デカい仕事」では、実際結構な確率で いま出ているような物を使うことになると思う。
370 名前:デフォルトの名無しさん mailto:sage [2009/08/09(日) 22:02:12 ] 危険な機能を使わないためと言って変な黒魔術で無理矢理回避する方がよっぽど危険だしな
371 名前:デフォルトの名無しさん mailto:sage [2009/08/09(日) 22:25:27 ] Windowsでプログラムしていると reinterpret_cast と dynamic_cast のオンパレードですよ^^
372 名前:デフォルトの名無しさん mailto:sage [2009/08/09(日) 22:30:33 ] >>371 キャストが必要になるのはわかるが、オンパレードはおかしいだろ。 同じ意味のキャストはてきとうにラップしろよ。
373 名前:デフォルトの名無しさん mailto:sage [2009/08/09(日) 22:39:44 ] ダウンキャストの意味わかってるのか? 存在しないメンバにアクセスして鼻から悪魔が出るのを承知で 使わないといけないんだぞ
374 名前:デフォルトの名無しさん mailto:sage [2009/08/09(日) 22:43:35 ] HWND(構造体へのポインタ)をCWndクラスにキャストさせたり、Windowsプログラミングは楽しいなぁ^^
375 名前:デフォルトの名無しさん mailto:sage [2009/08/09(日) 23:12:24 ] C++やりたての頃はこういう鼻から悪魔の意味もわからなかった #include <iostream> class Base { int i; public: virtual void print() const { std::cout << "Base" << std::endl; } }; class Derived : public Base { public: void print() const { std::cout << "Derived" << std::endl; } }; int main() { Base *p; p = dynamic_cast<Derived*>(new Base); p->print(); // ouch! }
376 名前:デフォルトの名無しさん mailto:sage [2009/08/09(日) 23:17:31 ] >>375 これはどの辺が鼻から悪魔?
377 名前:デフォルトの名無しさん mailto:sage [2009/08/09(日) 23:18:56 ] >>376 BaseにはDerived::print()がない 実行してみればわかるが正しく動かない
378 名前:デフォルトの名無しさん mailto:sage [2009/08/09(日) 23:20:46 ] >>376 dynamic_cast<Derived*>(new Base) この結果がヌルポインタになる。 その後の p-> でヌルポインタをデリファレンスして未定義動作。
379 名前:デフォルトの名無しさん mailto:sage [2009/08/09(日) 23:21:39 ] >>377 えっ?
380 名前:デフォルトの名無しさん mailto:sage [2009/08/09(日) 23:25:38 ] ごめんこういう場合に使うんだったね #include <iostream> class Base { int i; public: virtual void print() const { std::cout << "Base" << std::endl; } }; class Derived : public Base { public: void print() const { std::cout << "Derived" << std::endl; } }; int main() { Base* p; p = dynamic_cast<Base*>(new Derived); if (!p) std::cout << "dynamic_cast failed." << std::endl; p->print(); // ouch! }
381 名前:376 mailto:sage [2009/08/09(日) 23:27:43 ] すみません >>377 と >>378 はどちらが正しいですか?
382 名前:デフォルトの名無しさん mailto:sage [2009/08/09(日) 23:29:07 ] >>381 >>378 が正しい ダウンキャストはポインタが正しい本体を指している時にのみ成功する
383 名前:デフォルトの名無しさん mailto:sage [2009/08/09(日) 23:37:32 ] >>380 これは何でouch!なの?
384 名前:デフォルトの名無しさん mailto:sage [2009/08/09(日) 23:38:21 ] >>380 いや、 Derived* → Base* は暗黙変換で通るから、 dynamic_cast の出番じゃない。 しかも、せっかく dynamic_cast の結果にチェックを入れたのにメッセージ表示の後に 結局 p-> してたらダメじゃん。
385 名前:デフォルトの名無しさん mailto:sage [2009/08/09(日) 23:40:07 ] わかんね dynamic_castの正しい使い方知ってる人教えて
386 名前:デフォルトの名無しさん mailto:sage [2009/08/09(日) 23:48:07 ] DerivedがBaseとBase2を継承してるとして ・Derived* → Base* (アップキャスト) 常に成功し、Baseのポインタが得られる ・Base* → Derived* (ダウンキャスト) DerivedのBase部分を指してるポインタだったら正しいDerivedのポインタが得られる そうでなければヌルポインタが返ってくる ・Base* → Base2* (クロスキャスト) DerivedのBase部分を指してるポインタだったら正しいBase2のポインタが得られる そうでなければヌルポインタが返ってくる ・Base* → int* (無関係) 常にヌルポインタが返ってくる 参照の場合は、以上の「ポインタ」を「参照」、「*」を「&」、 「ヌルポインタが返ってくる」を「std::bad_cast例外が投げられる」に読み替えればいい
387 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 00:01:23 ] よく見ろよw >>375 のは p = dynamic_cast<Derived*>(new Base); どこにもDerivedのインスタンスは生成されない そりゃNULLが帰ってくるだろうって
388 名前:357 mailto:sage [2009/08/10(月) 00:18:37 ] >>358-359 ありがとうございます。 NaNについてはもっと勉強してきます。
389 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 00:45:20 ] >>369 そういう話ではなく > 「できればこれを使わずに済ませたいものだが・・・」 といったらそれは使うフラグ
390 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 01:35:06 ] >>389 まさにそういう話だと思うが。
391 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 02:23:56 ] 仕事のデカさは関係ないってことじゃないの?
392 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 12:33:39 ] dynamic_castの意味を今まで勘違いしてたわ ダウン・キャストしても安全に使用できるかどうかの判定なのね
393 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 15:40:20 ] VS2008のVC++MFCで ボタンクリックでピクチャーコントロールにjpgファイルの画像をサイズを変えて表示しています。 以下ソース CImage img; CImage img2; HDC hdc; img2.Create(80,60,24); img.Load("jpgファイルのフルパス"); hdc = img2.GetDC(); SetStretchBltMode(hdc, HALFTONE); img.Draw(hdc, 0, 0, 80, 60); img2.ReleaseDC(); m_xcPic01.SetBitmap( (HBITMAP)img2 ); img.Destroy(); img2.Detach(); img2.Destroy(); jpgファイルが変わる毎に、画面上の画像も切り替えたいので 上の処理を呼び出して、画面を切り替えてます。 しばらく動かしていたところで気付いたのですが、 メモリの使用量がかなり多くなっていました・・・ ファイルロード側のDestroyやリサイズ後側のDetach、Destroyだけでは解放してくれないのでしょうか? わかる方、または参考になるサイトやスレをご存知の方、よろしくお願いします。
394 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 15:45:28 ] Detachしてしまったビットマップは削除されないのでは
395 名前:デフォルトの名無しさん [2009/08/10(月) 15:48:42 ] ヘッダーに変数を定義することって出来たんでしたっけ? いや、さっき書いてみたら出来たんで、ちょっとびっくりしたんですが。 インクルードガードしてないとエラーが出るってだけなのかな。Cではどうなんでしょう。 まあ、作法としてはインクルードガードしててもやっちゃダメなのかもしれないですけど。ですよね?
396 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 15:54:56 ] 本当ならリンカが多重定義のエラーを吐くはずだが、デフォルトでは吐かない奴もいる
397 名前:393 mailto:sage [2009/08/10(月) 15:58:12 ] >>394 レスありがとうございます Detach後にDestroyすると、メモリ上に残る・・・ つまり、リサイズ後用のimg2がどんどん溜まっている状態 ってことでしょうか? ためしにimg2.Detach();をコメントアウトして動作させると、 別ウィンドウの後ろに隠れると画像が消えると言う症状がでました。 私、根本的に作り方を間違えているのかも・・・
398 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 16:18:59 ] >>397 MFCスレでやってくれ
399 名前:393 mailto:sage [2009/08/10(月) 16:28:29 ] >>398 MFC相談室の方に移動させていただきます。 スレ汚しすみませんでした。
400 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 16:45:42 ] >>395 ヘッダだからできない事というのはないよ やるべきじゃないことは、ある。
401 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 17:42:52 ] >>400 >ヘッダだからできない事というのはないよ へー、そうなんですか。 逆に、ソースだとできないことってのはありますよね? テンプレートの定義とか。
402 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 18:00:51 ] >>401 .hも.cppもC++の上では本質的には変わりないんだよ。 テンプレートの定義だって、別に.cppの上でやったっていい。 その定義が他の.cppから見えるかどうかは別問題だがな。
403 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 18:06:33 ] >>401 だからできないことはないって。 逆に聞くが、ヘッダとソースってどうやって区別してんの?
404 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 18:08:23 ] 定義そのまま他の.cppに丸ごとコピペすればいいわけだが、 後々修正する際に全部直して回るのが面倒だからそういうことはやらないだけだ
405 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 18:09:46 ] #include "header.cpp" この場合、header.cpp はヘッダなのかソースなのか
406 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 18:38:26 ] >>405 いわゆるクソコードってやつだよ。
407 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 18:46:46 ] オブジェクト指向について質問なんだけど。 クラスAのインスタンスをクラスBで作り クラスBのメソッドからクラスAのprivateにあるメンバ変数をゲッターセッターを使って弄る(クラスBのメンバ変数にも同期させる)。 そして、又クラスCのメソッドからクラスBにあるメンバ変数を参照して、判定なりをする。 そういう風に包含を重ねて行くのがオブジェクト指向なの? C++をやって間もないんだけど、俺のプログラムはこんな感じなんだ。 良いのか悪いのか分からない、アドバイスお願い
408 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 18:48:16 ] >>405 学生の時にバイトしていた会社のコードにそういうのがあった 日本のロケットがクソ高くて落ちるわけだ、と思った
409 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 18:54:57 ] クソコードでバグを入れて、 そのバグを取るのが仕事ですから それでいいんです。
410 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 18:56:03 ] >>407 俺はメソッドとかC++標準にない用語を使われても起こらない。 しかし >>クラスAのインスタンスをクラスBで作り これはどういう意味だい?
411 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 18:58:28 ] >>410 えっと クラスBのprivate領域に、クラスAの実体を包含するって意味で書いたつもりだった
412 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 19:03:01 ] >>406 クソかどうかは関係ない。 できないことがあるのかどうかが論点であり、やるべきではないことはまた別の話
413 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 19:44:54 ] >>407 >又クラスCのメソッドからクラスBにあるメンバ変数を参照して、判定なりをする。 クラスBでクラスBのメンバ変数を参照して判定するようにして、外からメンバ変数を 見せないように隠蔽するのが、オブジェクト指向のカプセル化の基本かな。 セッタ/ゲッタはそれを破ってしまうから避ける様に設計するのがお勧め。
414 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 20:12:31 ] 雪駄とか下駄はオブジェクト指向じゃないと個人的には思う。 単一責任原則をはたすためにも、 メソッドは単に状態を書き換えるだけでは十分でないと思うから。
415 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 20:15:25 ] セッタ/ゲッタは最終手段であり、 それに突入した瞬間からクソコードが始まると考えて 「一般には」さしつかえないくらい。
416 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 20:33:13 ] C++ code - 95 lines - codepad ttp://codepad.org/xR4PHa3G この std::numeric_limits の明示的特殊化のコードは、 g++ 4.4.0では問題無くコンパイル・実行できました。 しかし Microsoft Visual Studio 2008 Version 9.0.30729.1 SP では error C2910: 'std::numeric_limits<MyTempl<MyInt>>' : 明示的な特殊化にすることはできません。 となり、コンパイルエラーとなってしまいます。 VCでも通す方法はありませんでしょうか? Compiler Error C2910 ttp://msdn.microsoft.com/en-us/library/cx7k7hcf(VS.71).aspx このあたりを読んでみましたが、よく分かりませんでした。 よろしくお願いします。
417 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 20:52:34 ] stdの中を無理矢理いじくってるからかなあ 多分ヘッダーlimitsのどこかとぶつかってるよ
418 名前:416 mailto:sage [2009/08/10(月) 20:56:41 ] std名前空間は 新しい物を追加したりすれば未定義の動作となる。 しかし関数・クラステンプレートの特殊化のみ 認められる。 ということは知っているのですが、 私のやり方がまずいのでしょうか。。。
419 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 20:57:14 ] template <typename MyInt> この行いらない
420 名前:416 mailto:sage [2009/08/10(月) 21:04:44 ] すみません。 その辺確かにまずかったです。 C++ code - 95 lines - codepad ttp://codepad.org/yovzUoIJ これはどうでしょうか? やりたいことは template <typename hoge_t> struct numeric_limits< MyTempl<hoge_t> > : numeric_limits< hoge_t > の部分で現れていると思います。
421 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 21:07:00 ] template <typename hoge_t> の前の template <> が要らないんじゃ
422 名前:416 mailto:sage [2009/08/10(月) 21:25:35 ] >>421 それで通りました! 皆様ありがとうございます。 本気で助かりました。。。
423 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 21:32:54 ] そのままで通るBCC6.1.3は欠陥コンパイラという事か
424 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 21:36:47 ] いやg++も通っているから別に欠陥ではないのでは? VCが厳しいのかな。 g++ + 訂正前 -> 通る g++ + 訂正後 -> 通る VC++ + 訂正前 -> 通らない VC++ + 訂正後 -> 通る BCC6.1.3 + 訂正前 -> 通る BCC6.1.3 + 訂正後 -> ??? 訂正後はBCCで通る?
425 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 21:43:25 ] >>424 訂正後も通るよBCC
426 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 21:47:26 ] g++ + 訂正前 -> 通る g++ + 訂正後 -> 通る VC++ + 訂正前 -> 通らない VC++ + 訂正後 -> 通る BCC6.1.3 + 訂正前 -> 通る BCC6.1.3 + 訂正後 -> 通る じゃあ通る動作と通らない動作、 どっちが規格的には正しいのだろう?
427 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 21:55:42 ] BCCは歴代的にテンプレート周りが怪しいとして(もっとも 今回のバージョンからboostに部分的に対応しているんだが) g++が通ってるんだからvc++が厳しすぎるんじゃね?
428 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 22:29:15 ] @aaaaaaaaa.cpp ttp://codepad.org/8b4slwrj こうすると、VC++では error C3767: 'foo': 候補の関数はアクセス可能ではありません。 'aaaaaaaaa.cpp(26)' の friend 関数である可能性があります : 'foo' [引数依存の 照合を使って検出される可能性があります] というエラーになります。 ところが namespace MyNS を外してグローバルスコープにすると ttp://codepad.org/nBmNHA3H このコードのようになりますが、VC++で通ります。 なお、g++ではどちらも通ります。 Aまた、//問題の箇所2の行をコメントアウトした C++ code - 50 lines - codepad ttp://codepad.org/J3kjckz1 はg++, VCどちらも通らなくなります。 (インスタンス化されていないため?) @Aの問題の原因としては //問題の箇所1 あたりのやりかたがまずいのかと思っているのですが、 正解のコーディングをご教示いただけますでしょうか? よろしくお願いいたします。
429 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 22:55:18 ] BCC6.1.3はg++に準ずる結果となりました VC++だけ挙動が違うね
430 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 23:07:02 ] VC++, g++, BCC 以上に 標準C++準拠度が高いコンパイラって無いのかな? 性能は悪くても良いから標準C++準拠度だけを命にしているコンパイラ。
431 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 23:17:19 ] Comeau C++とかか?
432 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 23:20:27 ] using namespace MyNS;で通るね MSDNによると Friend function names are no longer introduced into containing namespace だそうなのでMyNS::fooの時点でADLが利かなくなるってことかな?規格なんて読んだことないから知らないけど。
433 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 23:22:02 ] 補足 using namespaceしてからMyNS::fooをfooだけに
434 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 23:34:50 ] 違いますか? どのあたりが違いますか?
435 名前:430 mailto:sage [2009/08/10(月) 23:35:35 ] Comeau C/C++ - Wikipedia, the free encyclopedia ttp://en.wikipedia.org/wiki/Comeau_C/C%2B%2B こんなん初めて聞いた俺がいる。 ありがとう。>>431
436 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 23:36:44 ] 事実上exportキーワードに対応させてるコンパイラは 今の所これだけだしな
437 名前:434 mailto:sage [2009/08/10(月) 23:37:55 ] 誤爆しました。 失礼しました。
438 名前:428 mailto:sage [2009/08/10(月) 23:56:23 ] Comeau C++のWebサイトで で ttp://codepad.org/J3kjckz1 を実行してみました。 Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2 Copyright 1988-2008 Comeau Computing. All rights reserved. MODE:strict errors C++ noC++0x_extensions "ComeauTest.c", line 44: error: namespace "MyNS" has no member "foo" MyNS::foo<double>(MyNS::MyTempl<MyNS::MyInt>()); ^ "ComeauTest.c", line 44: error: type name is not allowed MyNS::foo<double>(MyNS::MyTempl<MyNS::MyInt>()); ^ 2 errors detected in the compilation of "ComeauTest.c". だそうです。
439 名前:デフォルトの名無しさん mailto:sage [2009/08/11(火) 00:01:41 ] という事は例のダイヤモンド継承のバグを除けば VC++の方が標準に近いわけか
440 名前:428 mailto:sage [2009/08/11(火) 00:05:46 ] >>420 の ttp://codepad.org/yovzUoIJ のtemplate <>あり&無しについて g++ + 訂正前 -> 通る g++ + 訂正後 -> 通る VC++ + 訂正前 -> 通らない VC++ + 訂正後 -> 通る BCC6.1.3 + 訂正前 -> 通る BCC6.1.3 + 訂正後 -> 通る Comeau C++ + 訂正前 -> 通らない Comeau C+++ 訂正後 -> 通る でした。
441 名前:428 mailto:sage [2009/08/11(火) 00:07:05 ] >>428 の@の ttp://codepad.org/8b4slwrj ttp://codepad.org/nBmNHA3H は両方とも通りません。 (VC++で通った)グローバルスコープにおいたら方のttp://codepad.org/nBmNHA3H でも Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2 Copyright 1988-2008 Comeau Computing. All rights reserved. MODE:strict errors C++ noC++0x_extensions "ComeauTest.c", line 41: error: identifier "foo" is undefined foo<double>(MyTempl<MyInt>()); ^ "ComeauTest.c", line 41: error: type name is not allowed foo<double>(MyTempl<MyInt>()); ^ 2 errors detected in the compilation of "ComeauTest.c". となりました。 どうやらComeau C++が正しいとすれば、 私の@のコードはどちらも「通る方がおかしい」コードという事になるようです。
442 名前:デフォルトの名無しさん mailto:sage [2009/08/11(火) 15:32:28 ] 気になったので少し調べてみた でも憶測も入ってるので間違ってたら突っ込みキボン 1. グローバルかMyNSかで違う クラス内で定義されたfriend関数はADLを通してしか利用できないっぽい なので、定義をグローバルに置いたからじゃなくて、 利用側で名前空間を指定しなくなったからコンパイルが通るようになるんだと思う 2. それでもComeauでは通らない これはワカンネ 関数テンプレートのテンプレート実引数が暗黙的に決まるようにして、 関数呼び出し時に明示的な指定をしないように変えたら、MyNSに入っていてもコンパイルできるようになった 明示的にテンプレート実引数を指定するとダメ 誰か理由を教えてくれ
443 名前:428 mailto:sage [2009/08/11(火) 15:55:47 ] ttp://codepad.org/405cfVvH とりあえずfooがテンプレートかつクラス内定義friend関数であることが問題である 可能性が高いと考え、 この様にbar関数(テンプレートでないクラス内定義friend関数)にしてみましたところ g++ 4.4.0 VC++ 2008 BCC5.5.1 Comeau C++ の4つで問題無くコンパイル・実行できました。 ちなみにbar(MyNS::MyTempl<MyNS::MyInt>());の場所を MyNS::bar(MyNS::MyTempl<MyNS::MyInt>()); にするとttp://codepad.org/wewb2LHcの様にエラーになります。 ::bar(MyNS::MyTempl<MyNS::MyInt>()); にしてもttp://codepad.org/hj2uJmG0の様にエラーになります。 グローバルスコープを明示的に指定するとダメになるところをみますと、 どうやら>>442 さんがおっしゃる1.が理由の一つである可能性が高いですね。
444 名前:デフォルトの名無しさん mailto:sage [2009/08/11(火) 15:59:07 ] どこで聞いたのか失念したけど friendとtemplateを併用するとADLがうまく働かなくなるって話を 聞いた事がある
445 名前:デフォルトの名無しさん mailto:sage [2009/08/11(火) 16:03:18 ] ちなみにbcc6.1.3では >MyNS::bar(MyNS::MyTempl<MyNS::MyInt>()); >にするとttp://codepad.org/wewb2LHcの様にエラーになります。 >::bar(MyNS::MyTempl<MyNS::MyInt>()); >にしてもttp://codepad.org/hj2uJmG0の様にエラーになります。 どちらも通ります どうもADL周りの作り込みが甘いのか構文解析の手抜きをしているのか
446 名前:428 mailto:sage [2009/08/11(火) 16:07:21 ] みなさんありあがとうございます。 とりあえずfriendにすることを諦めて、次のような逃げ道に走ってみました。 C++ code - 55 lines - codepad ttp://codepad.org/yBp6Lo3p こちらのコードは、 g++ 4.4.0 VC++ 2008 BCC5.5.1 Comeau C++ の4つで問題無くコンパイル・実行できました。 事前のインスタンス化なども不要なので、 逃げたような気がしてなりませんが一応解決はできました。。。
447 名前:デフォルトの名無しさん mailto:sage [2009/08/11(火) 16:16:22 ] 規格票を持っていたら§14.5.3 Friends を参照してみて欲しい いろいろと制限がきついことがわかると思う
448 名前:428 mailto:sage [2009/08/11(火) 16:45:41 ] >>447 すみません。 一介の趣味プログラマ(職業とは関係ない)でして、 規格票は買ってはおりません。 日本工業標準調査会:データベース-JIS詳細表示 ttp://www.jisc.go.jp/app/pager?id=40240 ここで探してみます。
449 名前:デフォルトの名無しさん mailto:sage [2009/08/11(火) 17:05:27 ] namespace MyNS { //省略 template<typename int_t> class MyTempl; template <typename hoge_t, typename boke_t> hoge_t foo(const boke_t& arg); template<typename int_t> class MyTempl { public : int_t num; MyTempl(int_t n = 0) : num(n) {} template <typename hoge_t> friend hoge_t foo(const MyTempl<int_t>& arg)//問題の箇所1 { return static_cast<hoge_t>(arg.num.num); } }; }//namespace MyNS
450 名前:449 mailto:sage [2009/08/11(火) 17:06:42 ] Comeau C++でコンパイルOK VC++2008で実行可能 だった。
451 名前:449 mailto:sage [2009/08/11(火) 17:16:19 ] template<typename int_t> class MyTempl; この前方宣言は要らなかった。スマソ。
452 名前:449 mailto:sage [2009/08/11(火) 17:17:00 ] namespace MyNS { //省略 template <typename hoge_t, typename boke_t> hoge_t foo(const boke_t& arg); template<typename int_t> class MyTempl { public : int_t num; MyTempl(int_t n = 0) : num(n) {} template <typename hoge_t> friend hoge_t foo(const MyTempl<int_t>& arg)//問題の箇所1 { return static_cast<hoge_t>(arg.num.num); } }; }//namespace MyNS
453 名前:428 mailto:sage [2009/08/11(火) 17:22:28 ] >>449 さん その方法なら テンプレートかつクラス内定義friend関数に できるのですね。 ありがとうございます。
454 名前:428 mailto:sage [2009/08/11(火) 17:47:41 ] >>449 さんのコードを記しました。 ttp://codepad.org/xotYKfl3 g++ 4.4.0 VC++ 2008 Comeau C++ では通りましたが、 BCC5.5.1 では通りません。 まあどうせBCCが悪いのだろうとは思いますが。 BCC6.1.3をお持ちの方、試していただけませんでしょうか?
455 名前:デフォルトの名無しさん mailto:sage [2009/08/11(火) 17:49:51 ] struct { ... } var; という感じで名前のないクラス/構造体を作れると思いますが、 これにコンストラクタ/デストラクタを付けたいなら名前を付けるしかないですか。
456 名前:デフォルトの名無しさん mailto:sage [2009/08/11(火) 17:51:28 ] ということは、 >>446 の言う逃げのコード(>>446 のttp://codepad.org/yBp6Lo3p) はbcc5.5.1ですら通る互換性の高いコードということか。 bcc5.5.1を見捨てるならどうでもいいんだろうけど。
457 名前:デフォルトの名無しさん mailto:sage [2009/08/11(火) 17:52:29 ] >>455 4章:クラス ttp://www5c.biglobe.ne.jp/~ecb/cpp/04_15.html
458 名前:デフォルトの名無しさん mailto:sage [2009/08/11(火) 17:56:08 ] >>454 エラー E2015 codepad9.cpp 49: 'MyNS::double foo<double,MyNS::MyTempl<MyNS::MyInt> >(const MyNS::MyTempl<MyNS::MyInt> &) at codepad9.cpp:8' と 'MyNS::double foo<double>(const MyNS::MyTempl<MyNS::MyInt> &)' の区別が曖昧(関数 main() ) と出てしまいます
459 名前:428 mailto:sage [2009/08/11(火) 18:02:27 ] >>458 ありがとうございます。 BCC6.1.3でも無理なようですね。 ・・・ちなみに、 少し改変した ttp://codepad.org/LQvoBRSP g++ 4.4.0 VC++ 2008 Comeau C++ では通りましたが、 BCC5.5.1 では通りません。
460 名前:デフォルトの名無しさん mailto:sage [2009/08/11(火) 18:10:33 ] >>457 #include <cstdio> class { int foo; public: void func() {printf("Whee!:%d\n", foo);} void set(int v) {foo = v;} } bar; int main() { bar.set(3); bar.func(); return 0; } -- 無事に実行できるけど?
461 名前:デフォルトの名無しさん mailto:sage [2009/08/11(火) 18:11:59 ] >>460 元質はコンストラクタ/デストラクタが作れるか聞いているのは判る?
462 名前:457 mailto:sage [2009/08/11(火) 18:12:22 ] >>460 正直スマンかった。
463 名前:デフォルトの名無しさん mailto:sage [2009/08/11(火) 18:17:56 ] >>460 つまり、そのサイトはダメダメということで宜しいか?
464 名前:デフォルトの名無しさん mailto:sage [2009/08/11(火) 18:34:44 ] >>459 エラー E2015 codepad10.cpp 59: 'MyNS::double foo<double,MyNS::MyTempl<MyNS::MyInt> >(const MyNS::MyTempl<MyNS::MyInt> &) at codepad10.cpp:8' と 'MyNS::double foo<double,MyNS::MyInt>(const MyNS::MyTempl<MyNS::MyInt> &) at codepad10.cpp:38' の区別が曖昧(関数 main() ) となってやはりbcc6.1.3でも無理です
465 名前:428 mailto:sage [2009/08/11(火) 18:45:35 ] >>464 Borlandはこのあたり伝統的に対応がおそいようですね。 ありがとうございます。
466 名前:デフォルトの名無しさん mailto:sage [2009/08/11(火) 18:50:23 ] template <typename T> bool is_not_zero(const T& arg); テンプレート引数T型はint型からT型へ暗黙のキャストが可能なものを選ぶとするとき、 operator!=(const T&, const T&)が定義されていれば template <typename T> bool is_not_zero(const T& arg) {return arg!=static_cast<T>(0);} とし、定義されていないならoperator==(const T&, const T&)を利用して template <typename T> bool is_not_zero(const T& arg) {return !(arg==static_cast<T>(0));} とする。 こんな方法は可能でしょうか? 可能でしたらご教示ください。
467 名前:デフォルトの名無しさん [2009/08/11(火) 18:56:51 ] 今朝来たMSDNのメールて、 【64 ビット プログラミング ガイド日本語版を公開中!】 次世代 Windows 環境に備えよう なんてのが届いたので、みていたら。 int i1 = -2; unsigned int i2 = 1; char *s = "Hello"; printf("%s", s + 1 + (i1 + i2)); このコードは32ビットなら動くけれども、64bitだと修正しろとあります。 ぱっと見た目変なところはなさそうにみえるのですが・・・ 1.int が 64bit → 問題なし 2.int/unsigend は 32bit で64bit int にキャストされる → 問題なし 3.int + unsigned = unsigned → 0x000000000ffffffffL になるから? なんで long int になんねーんだよwなのだろうか? 64bitもっている人誰かいたら解説ください。
468 名前:デフォルトの名無しさん mailto:sage [2009/08/11(火) 19:00:50 ] そんな不気味なコード書かないだろうたぶん たしかWindowsはlongも32ビットだから、size_tやptrdiff_tを使わないとだめなんじゃ?
469 名前:デフォルトの名無しさん mailto:sage [2009/08/11(火) 19:40:33 ] printfの行がキモすぎるwww たぶんポインタまわりのことを言いたいんだと思うが。