テンプレ終了。例のやつは、そろそろ飽きたんで好きな人は勝手にやって。
STLつかうと一気に実行ファイルサイズが10倍に?! 環境によるだろ。 俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力 ランタイムを使用するようにして使っているが、例えばstd::vectorを 使っても使わない時と比べ10Kほどしか増えない。 すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。 C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。 とかいうエラーが出るんだけどこれってどうすればいいの? #include <stdafx.h> 後死ね。 言葉が悪いな。それで教えているつもりか。 まぁヒントぐらいにはなったな。 うむごくろう。
13 :
デフォルトの名無しさん :2006/07/17(月) 07:06:31
>STLつかうと一気に実行ファイルサイズが10倍に?! 懐かしいwこれ書いたの俺だww
>環境によるだろ。 懐かしいwこれ書いたの俺←本当です。
15 :
デフォルトの名無しさん :2006/07/17(月) 08:08:49
>>14 ほんと!?
このスレって3人くらいしかいないんじゃないの?
じゃぁ指摘してあげる。
>ランタイムを使用するようにして使っているが、例えばstd::vectorを
>使っても使わない時と比べ10Kほどしか増えない。
これさ、テンプレート引数を変えるたびに10KBずつ増えるってことでしょ?
それぞれ別のクラスに対するvectorが10個あったら100KBだよね?
100個あったら1MB。
環境によらず、一気に10倍なんじゃないの?
ちなみに俺が10倍って書いたのは冗談だよw
>>15 いや、今はさすがにわかってる。
BCCのバージョンもBDS2006のを使ってるから5.82に上がってるし。
わざわざ書いてくれてスマン。あの頃は俺も初心者だった。
和んだ
流されてしまったようなのでもう一度お願いします class C { public: void setHoge(@) { ... } A getHoge() { ... } private: tr1::shared_ptr<Hoge> hoge_; }; このようなクラスがあったとき、@とAはHoge*かtr1::shared_ptr<Hoge>の どちらにするのがいいのでしょうか? Aはユーザーが誤ってdeleteできないようにtr1::shared_ptrを返す べきとは思うのですが
19 :
デフォルトの名無しさん :2006/07/17(月) 12:49:30
>>18 俺だったら1も2もshared_ptrにするな。
>>18 その2択なら shared_ptr しかあり得ない。 Hoge* を使うと
- set に new されてないポインタが渡されたら...
- 気づいているようだが get で返したポインタを delete されたら...
前スレで言われてたように、ポインタの set/get なんて無くすことができれば
一番いいんだけどね。
setterはもうアンチパターンだな
>set に new されてないポインタが渡されたら... というのはshared_ptrを知っているユーザーなら決して newしてないオブジェクトを渡さないから少しはマシってことでしょうか? set/get はない方がいいとは思いますがあらゆるものが不足してなくせないんです interfaceをどうとかと言っていた方がいましたが・・
>>22 例えば、
class Person {
public:
explicit Person(int age) : age_(age) {}
...
private:
int age_;
};
のようなクラスがあった場合もsetはない方がよいですか?
時代はImmutableなのでしょうか?
>>24 Person に含まれるほかの情報との整合性が無いなら全部 public な構造体にする。
整合性が必要なら、ほとんどの場合は「年齢をセットする」という単一の操作が
意味を成さないことになるので、そんなインターフェースは要らない。
26 :
25 :2006/07/17(月) 13:46:49
言い切るとちょっとまずいな。要は set/get なんてのを書きたくなったときは、 書かなくていいコードを書いてるんじゃないかと疑う余地があるってことだ。
難しくて良く理解出来ませんでしたが、要するにこういうことでしょうか? ・ageが他のメンバと関係ないデータならageをpublicにして、直接アクセス ・ageが他のメンバと関係有る場合、ageだけを変更するなんて操作はいらない 見当違いなこと言ってたらすいません・・
>>23 引数の型を shared_ptr にしとけば shared_ptr を渡すか、
shared_ptr のコンストラクタを使った明示的な変換を必要とするので
間違いがあっても気づきやすいってこと。
「決して〜」とは言い切れないけど、だいぶマシとは言える。
set/get については、
>>25-26
29 :
25 :2006/07/17(月) 14:00:52
>>23 > set/get はない方がいいとは思いますがあらゆるものが不足してなくせないんです
それを詳しく説明しない限り、shared_ptrでいいかどうか説明できないでしょ?
外でどう使われるか説明してないんだから。
要するに、書かなくていい不要なコードを書いているという点で
setterはアンチパターンになりうるということですよね?
age_に大して何らかの前処理や後処理をする必要が有る(または予期される)場合など
(例えばマルチスレッドで同期を取る)可能性がある場合、setterは避けられませんか?
>>30 不足しているのは私の頭です
それに、どうも今まで読んできた本の内容を素直に受け入れすぎる傾向もあるようです
>>24 Person son2(son1.age());でいいからね
まあImmutableパターン知ってるなら>>25-のアドバイスは聞かないことだ
つーかdataをpublicにするな
33 :
25 :2006/07/17(月) 15:47:34
>>32 データを public にするなというのもクラスとしての整合性を
前提にしたルールであって、整合性の必要無いデータについて
盲目的に適用するものではないと考える。
データを組み合わせただけの構造体のほうがクラスよりも単純だ。
明確な必要性が無い限り単純さを損なわないほうがいい。
34 :
デフォルトの名無しさん :2006/07/17(月) 16:23:31
shared_ptrとそのsetter/getterだけあって、 どうですか?って聞かれても困るよね。 shared_ptrだけじゃまずいの? って思うけど… なぜclassにする必要があるのかわかりません。
同 志 社 同志社同志社同志社 同 志 社
同 志 社 同 同志社同志社同志社 社 同 志 社
>>27 年齢という数値だけを持つPersonというクラスを
class Person {
public:
explicit Person(int age) : age_(age) {}
int getAge() const { return age_; }
void setAge(int x) { age_ = x; }
private:
int age_;
};
と実装して、クライアントに "Person a; int age = a.getAge();" と
書かせるようにするか、もしくは簡潔に
struct Person { int age; };
と実装して、クライアントに "Person a; int age = a.age;" と
書かせるようにするか、どっちがいいのかってこと。
…と考えればわかりやすいかな?
一般に、あるクラスのすべてのデータメンバが他のデータメンバと完全に独立してて、
外部とのインタフェースがget/setしか存在しないなら、
上記のどちらでも良くて好みの問題。
前者はデータメンバをprivateにしているが、実際のところ隠蔽している意味がない。
# ただ、前者からsetだけ取り外すと若干様子が変わるけど
>>33 が言っているのは、意味的に等価なら前者のコードは単なる無駄なんじゃないか
ってこと。漏れも同意で、盲目的な雪駄と下駄は個人的には面倒なので使わないな。
だからっつってageをpublicにするのは馬鹿。 雪駄、ゲッタをとりあえず盲目的にでもつけとくのは正解
二行目、ageをpublicにするぐらいなら、が抜けていた
int value = obj.GetValue(); value++; obj,SetValue(value); みたいな文が増えるくらいならpublicにしてる。 それ以外ならとりあえずprivateにしてセッターゲッターかな
もう、publicなメンバ変数を言語的に禁止してもいいころじゃないか
>>38 「僕の大好きな雪駄、ゲッタを悪く言うやつなんてみんな馬鹿だ!」ってことか。
小学生かよ。
プログラムするならもっと論理的に考えな。
雪駄、ゲッタよりpublicの方が優れている理由を、論理的に説明してください。
>>43 だれがどっちが優れてるなんて話をしている?
盲目的なコードを書くんじゃなくて、理由に基づいて書けってことだ。
>>43 「整合性の必要が無いデータ」とはどのようなものですか。
>>45 どちらかがより目的に適合するなら、それは優れているというのではないですか。
「盲目的な」という言葉で、もうこいつとは議論する価値なし。 したいようにすればいいよ。
>>47 紙を切るという目的にはカッターナイフが適合する。
木片を切るという目的にはノコギリが適合する。
しかしどっちが優れているとも言えない。
プログラムするならもっと論理的に考えな。
>>48 リンク先を読みましたが、最後のBjarne Stroustrupの発言を意図的に
無視しているのは何故ですか。
>>51 最後のって、でかいな。どこのつもりだ。どこにしても無視してるつもりは無いけど。
>>52 あなたの発言は、Bjarne Stroustrupの最後から二番目の内容を
恣意的に解釈しただけのものではありませんか。
>>43 常に一方が勝るというほどの差はない。文脈によって良かったり悪かったりだろう。
想定される使用状況ではある一方が有利と判断できるなら、それを選べばいい。
例えば、既存のコードに追加するときや開発チーム内でのルールがあるときなどは、
周囲のコードやルールに合わせておくべき。
>>48 なかなか丁寧で面白いね。"Classes Should Enforce Invariants" という題名が秀逸。
「不変条件がないならクラスにするべきではない」ってところ?
>>50 紙を切るという目的において、カッターナイフとノコギリの
どちらかが優れているということも出来ませんか。
EffectiveC++ではセッタゲッタにすべき理由を書いてあったんじゃないかな。
>>53 2番目の内容からさらに一部だけ意訳した。
恣意的で間違っているというならさっさと指摘してくれ。
まどろっこしい。
>>56 同感です。
ageごときにsetter, getterを付けるのは常に冗長のような決め付けは、
そちらの方が盲目的に見えます。
>>56 その理由がプログラムとマッチすれば使えばいい。盲目的に使うのは無駄で迷惑。
>>60 では、publicの方が優れているというのですね。
>>60 つまり、あなたが「単純なデータ」だと思うようなメンバ変数の場合は、
相手はいつでも「盲目的にsetter/getterを作っている」と思っていると
いうことですね。
相手って誰?
この議論、どこに向かわせようとしてるんだ?>参加者w
publicにするか、setter/getterにするかの議論のための理論武装ですが?
メンバ変数をpublicにするときのexcuseの練習でしょう。
あー盲目的にセッタゲッタ化するアホいたわ commentまでネチネチつけてた 時間の無駄だってのに・・・
>>42 僕の大好きなpublicデータメンバを悪く言うやつなんて皆バカだ」ってことか
小学生はおのれじゃボケ!
ageをひとつ進める必要があるなら、それ用のI/Fを作るべきじゃなかろうか
本は所詮、机上の空論 ソース行数が多いほうが儲かるとき、オブジェクトっぽく見せたいとき、setter/getter 納期まで時間がないとき、public
クラスを作る場合の setter/getter vs public だと勘違いしている人が多いが、 元は(データを隠蔽した)クラスを作るべきかどうかって話だろ? 噛み合ってないよ。
まあsetter/getterは、データを隠蔽するだけが目的じゃナインだけど
>>56 せっかくなので拾ってきた。引用元は和訳第3版。
22項: データメンバはprivate宣言しよう
(ざっくり飛ばして最後)
覚えておくこと
・データメンバはprivate宣言しよう。それにより、データアクセスにおける構文の
一貫性、精度のよいアクセス制御、不変な条件の保証、クラスの制作者が実装を
変更できる柔軟性が得られる。
・protectedはpublicよりカプセル化を進めるものではない。
例えば、後からインタフェースを変更せずに内部機能を追加したいとき
(例えば外部から不可視のオブザーバを追加するなど)、
データメンバがprivateなら安心。てことか。
>>48 の引用元とは部分的に対立するね。どっちもどっちだなあ。
草鞋(わらじ) 草履(ぞうり) 樏(かんじき) 足袋 ・・駄目だ
ageはpublicなメンバ変数で、nameとaddressはsetter/getterでアクセスする? そんな無様なクラスは使いたくない。
setter/getterと生を混在させるのはやめて欲しいな。
>>77 それは駄目だろ。
実在はしてそうでイヤだが
クラスのメンバ変数をpublicにする奴はダメということで。
混在いやなの? じゃ「盲目的に」全てにsetter/getterを作るしかないねw
全部publicのものとsetter/getterのものに分ければいいじゃん。 俺はある程度規則性があれば一つのクラス内で混在させてもいいと思うけどな
メンバ変数が全部publicなクラス? そんな無様なクラスは使いたくない。
>>84 それはもうclassじゃなくてstructだろって話だろ。
>>81 そもそもgetter/setterをいちいち作って回ること自体設計失敗してるけどな。
そもそもageをコンストラクタで設定できるのにsetterが必要になる理由がわからん。 インクリメントするI/Fでもあれば済む話なんじゃないか?
それはageに固有の概念だと思う。 元々はポインタのset/getのようだし、もう少し話題は広いようだよ。
発端は
>>18 だけど、
>>24 、
>>27 、
>>33 が今の話題の元かな。
整合性の必要ない(つまり不変条件が壊れない)データの集合をカプセル化するとき、
「データメンバをpublicにしてget/setは使わない」のか、
「データメンバをprivateにしてget/setを使う」のか、
どっちがよりいいのかって話。
>>18 や
>>24 混乱してるかもしれんが、整合性が必要なデータを扱うとき(例えば生ポインタに
保持したメモリを勝手に開放されては困るとき)や、状態遷移に制約を付けたいとき
(例えば年齢は初期化後はインクリメントしかできないようにしたいとき)などは、
データメンバをpublicにするのはNGだ。これらの状況では、単純なget/setも
NGになるかもしれない(NGなことが多いと思う)。
setter/getterつけて満足してる奴、多そう
>>91 /*
|
|
|
∧|∧
( / ⌒ヽ | ̄ ̄ ̄ ̄ ̄ ̄ ̄
| | | |
∪ / ノ . |
ノ ノ ノ */
main (
)
{
}
すげえこの会話、一つの例外もなく頭が悪いw
何もわざわざ自分で頭が悪いと認める流れの中に 入らなくてもいいんじゃないかと思うんだがw
>>92 うわ、すげー懐かしい AA だ。
確か、俺が作ったんだった気がする。
この議論の滑稽なところは、「熟慮の結果publicメンバ変数にする」派が えらそうなところだ。この派閥は決まってsetter/getterを付ける奴を馬鹿にする。
お前の滑稽さには敗ける。
後で setter/getter に余計な処理つける可能性もあるのにね。
余計てw
付けないほうが良い処理ってことかw
「熟慮」の結果がpublicメンバ変数だというところが笑える
そもそもsetter/getterなんていうのがアレだな。 アクセッサとでも言いたまえ。
アラエッサ
少なくともこの流れの中に俺以外の馬鹿が一人いることを確信した。
105 :
デフォルトの名無しさん :2006/07/18(火) 13:42:40
ところで話は変わるが、 も前ら Point クラス (メンバは int x; int y; の2つ)って どうやって実装してる? private にして setter や getter 付けてる? 漏れは struct にしてるけど。
そのポイントクラスはどのような機能を持っているのか 語っていただこうか
画面やビットマップ上の位置を表すのに用います。 整数型の数値を2つ保持するのが機能の全てです。
なんでclassにするかstructにするか悩むんだ?
PODにするかどうかで悩んでるってことだろう
極座標変換が気になる人どうぞ ↓
PODSにはsetter/getterなど無い
漏れならアクセサは作るがセッタゲッタは作らないな。
PODSってクラスなの?
>>113 structとclassの違いはデフォルトがpublicかprivateかだけ。
PODなclassも存在するし、PODでないstructも存在する。
普段は108の言い方でも大体通じるが、こういう所でそれは期待できない。
PODなclassって、structと比べて何がいいの?
軽い
何が?
>>117 少なくともgccでは同じコードを吐く。
だから、PODであることを表明したければstructにするのがいいと思う。
おまんこ
A========================== void func(){ int hoge; for( int i=0; i < 777; ++i ){ hoge = 123; //hogeを使った処理 } } B========================== void func(){ for( int i=0; i < 777; ++i ){ int hoge = 123; //hogeを使った処理 } } なんか初心者目だと、Bはループの度にhogeを確保しなおして遅くなるイメージですが、 一般に ・A、Bどちらでもhogeは、関数の初めにスタックに確保される ・Bの方がスコープが限定されている分、最適化されやすい という認識で良いのでしょうか?
Javaじゃあるまいし、そのくらい最適化で消えてなくなる よって常にBで書く方がよい
Javaと何の関係があるのか分からない
for (int i=0; i < 10; ++i) { // scope A } // scope B i のスコープはどこまで? A だと思ってたんだけど、B までなソースに出くわした。
ソースっつーかコンパイラに依る
Aが正解。 でも外に漏れる実装は確かにあるな、VCとか。
>>125 ははー、どっちでも同じなんですね
レスありがとうございました
正確にはVC6以前がB、 VC7〜7.1はローカルスコープに同名の変数がない限りB、 VC8はデフォルトでA。
外に漏れるのが嫌な場合は #define for if(0); else for
一応書いておくと昔はBが正解だった。
今は昔
>>132 をつかえば
いまも昔も関係ないわけですね。
ありがとうございました。
VC6 でも?
昔がどうあれBはおかしい
だからこそ、B から A に仕様変更したわけだしな。
デストラクタで例外投げるなって聞いたんですけど、じゃあエラーが出たらどうすればいいんです? 例えばソケットとかcloseメソッドは当然作るとして、デストラクタでも念のためにcloseしますよね? そのときにエラーが出たら?
>>141 俺はエラーチェックしない。
そんなcloseなんてまず失敗するほうがおかしい、
せいぜい引数がおかしいなどと言った理由だろと決め付けている。
そして、もしエラーチェックしたければデストラクタに頼らず、自分でクローズする。
>>141 まぁエラーが出るような処理はデストラクタではまずやらんが、
やったとしても、ログ出して終わり。
>142-143 じゃあエラーが起こりうる場合はデストラクタでは資源解放しないってことでしょうか。 明示的にクローズするんですか?数が多くても? あとsocket closeはあくまでも例なんで、解放時にエラーの可能性はあるって前提でお願いします。
>>144 いやあのね、だからエラーが起こるような処理は基本的にはデストラクタでは
やらないって書いてるでしょ。
>>144 たとえばさ、資源解放が出来ないことが「致命的」な場合に、それをデストラクタでやって、
解放できないときの「異常」をデストラクタが飲み込んでしまうような設計をしたいんです、
とおまえさんは言っとるわけだ。
答えは、それが困るならデストラクタで解放するな、だ。
>>144 エラーの処理をデストラクタでやればいいじゃん。
まぁ、資源解放時のエラーでできる事なんかログを書く事ぐらいだと思うけど。
だから、
>>143 が正解だと思う。
始めにデストラクタありき、っていう
>>144 はキモイ。
>>141 Win32APIベースのプログラムなら SetLastError でも使ってあとから GetLastError で問題がなかったか調べろ。
それ以外の環境だったら似たようなグローバルエラー変数ソリューションを自作するなりして使え。
エラーが起こるような処理をデストラクタでやってるのってありがちじゃない? 1、エラーチェックしない 2、closeを別に作って呼ぶ 3、ログ吐く 4、GetLastError等を使う どれもいまいちだね。
>>150 基本3で、可能なら2もできるようにしておくのがいいんじゃないかな。
std::fstream なんか、そんな感じだね。
longjm・・・いや、なんでもない。
>>152 いや、それだったら例外と大して差がないから、結局同じ問題に帰着する。
・dtorではエラーチェックはするが例外は投げない。どうするかはケースバイケース。 ・終了処理用のmethodを別途作る。こちらは必要な例外を投げる。 と作っておき、エラーハンドリングをきちんとしたい時は2でやる。 簡便にやりたい時は1で済ませる。 というのはもはや定法です。
俺は144の気持ちも分かるな クライアントは、生成・削除以外の責任を持たなくて良いくらいのカプセル化の方が、気持ち良い 削除前に必ずrelease()を呼んでください…みたいのは嫌なんだよな まぁ、今はしょうがないのでそうしてるけど、次があったらどうにかして欲しいわ
デストラクタで例外を投げる可能性のあるメソッドを呼びたいときは、 きちんとcatchしといたほうがいいのでしょうか。
Effective C++ 第三版 ・デストラクタは例外を投げてはいけない。デストラクタ内で例外を投げる関数を呼び出す場合、 デストラクタがプログラムを中止させるか、その例外を補足し飲み込む(処理する)ようにする。 ・クラスのクライアントが例外に対処する必要があるなら、クラスに「例外を投げるかもしれない処理」 をする通常の関数(つまり、デストラクタでない関数)を付ける。
>>154 けっして定法ではないと思う。
ネットでも仕事でもよく見かけるのはエラーチェックしない糞プログラムばっかりだ。
>>158 えーとそれは「定法である」ということにケチを付けたいということでよろしいか?
たとえば、デストラクタで例外を投げたくなった場合、 その例外を受けたときどうしたいのかによって、答えは違うだろう。 ソケットクローズがエラーだったとして、それを検出したらどうするのかと。
二重例外でぐぐればこの話題は終了?
>>160 投げたくなっても、投げてはいけません。
>>161 ただし、一番上のやつは駄目で、二番目を参照すること。
>>164 それがおかしいだけ
お偉いさんが書くものすべて正しいと思ってるあほは氏ねば?w
んじゃ誰か正しい例を探してきてくれない?
なんかおかしくね? デストラクタで資源解放→close等でエラーの可能性がある→デストラクタで例外は禁止→エラーを黙殺するな で、初心者が困っててもどうすりゃいいのか妥当なサンプルも提示出来ないってことか 154は定法とまで言ってるのにな
デストラクタから例外が漏れるのを抑えるという理由を確認するために More Effective C++を久しぶりに読んだが、訳がひどいねえやっぱり・・・ しかし、例え初心者でも、この本は読むべきだろう。コード片を示せとか 言ってる奴がいるが、本で数ページを割いて説明している事を小さな コード片にまとめるのは至難の業。
>>169 だから何度も言ってるだろう。
リソースがリークして困るならデストラクタでやるな。
>>171 何言ってんだ?リソースの解放をデストラクタでやるのは何も問題ないだろ。
>>172 お前こそなに言ってんだよ。
「リークして困るなら」と言ってるだろうが。
デストラクタでリソースの解放をしないと、リークするんじゃないの?
そもそも誰もデストラクタで例外禁止なのは否定してないし、理由を聞いてるわけでもない。 ケースバイケースなのは分かったからサンプルを示してくれって話だろ。
いったい何のサンプルが欲しいんだよ?
サンプルって std::fstream じゃ不満なのか?
デストラクタで例外が出るとき、何処かでcatchしないとプログラムは死ぬだろ。 そうなると、ほかの処理ができなくなるんじゃないのか。 そんなトラップのようなデストラクタを持つクラス、使いたくないな。 自分だけで使うんなら、いいんだろうけどね
>>178 >そもそも誰もデストラクタで例外禁止なのは否定してないし、理由を聞いてるわけでもない。
>>169 違う。
黙殺していい場合にのみ、デストラクタでリソースの解放をやってもいい、が正解。
182 :
デフォルトの名無しさん :2006/07/21(金) 07:29:13
【 靖国神社とは … ”靖 国 機 関 説” 】
-----------------------------------------------------------------------------------
戦 前 : 官僚が天皇の名を騙り、国民を騙す戦争推進機関として設立。神を捏造。不遜、極まりない。
戦 後 : 官僚の戦争責任を、国民の戦没者追悼の念・祖先尊崇の伝統とすり替え、
数多の戦没者の中に埋没・隠蔽させる官僚のための官僚スキーム。
個人情報保護法が、国家経済破綻の責任者を隠す為の、隠蔽スキームであるのと同じ汚い手口!
-----------------------------------------------------------------------------------
影 響 : 戦後外交の足かせ。中国、朝鮮に付け入られる原因となった。尖閣しかり、竹島しかり!
今 後 : 古臭い靖国モデルは、21世紀日本にとって百害あって一利なし。破壊すべし。ってか、創価・靖国キモイ。
-----------------------------------------------------------------------------------
天皇陛下も国民とともに、官僚とその手先自民党と闘われていた事が判明!
【昭和天皇、A級戦犯合祀に反撃 …宮内庁長官メモ】(読売)
http://www.yomiuri.co.jp/national/news/20060720it06.htm 「親の心、子知らずとはこの事…」
【「増税して下さいと謝るまで削れ」、「病院・幼稚園つぶせ」首相、諮問会議で指示】
http://www.asahi.com/politics/update/0627/014.html
183 :
デフォルトの名無しさん :2006/07/21(金) 09:14:41
教えてください。 代入演算子のオーバーロードを定義するとき、戻り値をクラスの参照にするべきだと いうことをよく見るのですが、何故でしょうか? 例) Hoge というクラスがあったとして Hoge & Hoge::operator=(const Hoge& x) { //定義 } よく見る解説では a=b=cのような処理を実行するために戻り値は参照でなければ ならないといけないと書いてあります。 でも、以下のように値を返してもa=b=c は可能だと思えます。 Hoge Hoge::operator=(const Hoge& x) { //定義 } 戻り値を値にしてしまった場合、a=b=cが不可能となるようなケースってあるのでしょうか? よろしくお願いします。
コピーされていいなら好きにしろよ。 > a=b=cが不可能となるようなケースってあるのでしょうか? コピーコンストラクタが宣言だけされて、定義されてない時。
>>183 Hoge a, b, c;
(a = b) = c;
のように書いた際に、一時生成されたテンポラリオブジェクトにcが代入されて
a == cとならなくなってしまうから、必ず参照を返さなければいけない
VC6で、 cout << (int)(18.4*100000) << endl; と書いたときに、1839999 と表示されるのだが、 何か上手い回避手段は無いものか。
187 :
デフォルトの名無しさん :2006/07/21(金) 13:12:40
ちなみに、VC++7.1 でも同じだった。
>>186 - (int)(18.4*100000)
+ round(18.4*100000)
189 :
デフォルトの名無しさん :2006/07/21(金) 13:26:54
>>188 あーなるほど。確かに。
でも、やりたいのは端数切捨て処理だから、やるとすればこうか。
template< typename T > inline T fix( T value ) {
return ( value < 0 ) ? std::floor(value) : std::ceil(value);
}
面倒だけど、これでやってみるよ。
190 :
デフォルトの名無しさん :2006/07/21(金) 13:34:02
191 :
190 :2006/07/21(金) 13:38:20
あーーーでも、端数切捨てにすると、やっぱり
>>186 の問題が浮上してきやがる。
>>186 の提案もいいが、それだと 18.65 を端数切捨てで 18 と表示したいときに
19 と表示されてしまう。
どうしたもんだろ。
192 :
デフォルトの名無しさん :2006/07/21(金) 13:45:21
行列の計算で3行3列のaという行列とcという行列を定義したあと, これをそれぞれaaとccという行列にコピーしたいと思い, for(j=0;j<=m-1;j++){ for(k=0;k<=n-1;k++) aa[j][k] = a[j][k]; cc[j][k] = c[j][k]; } というプログラムを書いたのですが, aaの方はちゃんとaの行列になるんですが, ccの方が計算されずに全ての行列の値が0のままになってしまいます. aaとccのfor文の計算を分割すればちゃんと計算されるのですが, なぜこの場合同時にできないのでしょうか? どのようにすれば解決できるのでしょうか?教えてください.よろしくお願いします.
>>192 カッコ悪い。
慣れない内はforやifの後を必ず複文化しよう。
>>191 どこをどう丸めたいのかよく判らんが、sprintf()の"%.2f"で四捨五入して
sprintf()の"%.*s"で切り捨ててから数値化するとかw
まぁ、100倍して整数に四捨五入してから100で割って切り捨ててもいいんでね?
二進の無理数とか絡むようならどうやっても、最後は適当にごまかすしかないんじゃないか? 若しくは有理数クラスでも使う
196 :
190 :2006/07/21(金) 14:29:18
>>194 double rhs = strtod( TextBox1.Text().c_str() );
double lhs = strtod( TextBox2.Text().c_str() );
if( ... /* 整数表示フラグ */ )
{
stringstream s;
s << static_cast<int>( rhs * lhs );
TextBox3.Text( s.str() );
}
みたいなプログラムを組んでいて、仕様では
整数表示の際は端数を切り捨てることがきまっています。
>>186 の例のように
TextBox1 に 18.4、
TextBox2 に 100000 が代入された場合、
TextBox3 には 1839999 が表示されてしまうわけです。
両辺を n倍し、nで割る方式では上記問題を防げません。
とりあえず、↓の形で妥協することにしました。
int const n = 6;
sprintf( buf1, "%.*f", n, rhs * lhs );
sprintf( buf2, "%.*s", strlen(buf1)-n+1, buf1 );
TextBox3.Text( buf2 );
てか、intにcastするからだろ。 sprintf(buf, "%.0f", 18.4*100000); or std::cout << std::setprecision(0) << std::fixed << 18.4*100000 << std::endl;
198 :
デフォルトの名無しさん :2006/07/21(金) 15:16:13
>>197 >>196 に
> 整数表示の際は端数を切り捨てることがきまっています。
と書いてるように、丸めてしまっては意味がありません。
丸めてねーよタコ!節穴かお前。 こんな間抜けな質問するだけあるな。
>>199 sprintf()の"%.0f"なら四捨五入ですが何か。
int(d + floor(d)*DBL_EPSILON) でなんとかなりそだとおもうんだけど・・・ テストすんのが面毒背
203 :
183 :2006/07/21(金) 23:09:28
>>184 >>185 お二方よくわかりました。
クリアになりました。
本当にありがとうございました。
質問です。XP、.NET 2005 です。 あるヘッダファイル内で int hoge=3; と定義し、2つの cpp ファイル (a.cpp、b.cpp) からそのヘッダをインクルードすると、もちろんリンク時にエラーが出ます。 ところが、定義を const int hoge=3; とすると、エラーが出ませんでした。 これは、hoge と言う実体が2つ生成され、a.cpp と b.cpp の hoge はそれぞれ別のものを指していると考えてよろしいのでしょうか? ということは、スコープをファイル内に限定する static const int hoge=3; と同じ意味になるのでしょうか?
x = y; という式の結果は、xの持つ値でしょうか?それとも、xという名前のメモリ領域 (変更可能な左辺値)でしょうか?
>>205 そんなん試してみりゃすぐわかんじゃん・・・
>>204 C++ではconst int は定数扱い。
>>208 floatでもconstを付けると同じ現象となりますが、これはどう説明する気ですか?
>>204 constはデフォルトで内部リンケージを持っている。
//file1.c
const int hoge = 3;
//file2.c
const int hoge = 7;
としても文法違反ではなくリンクエラーにはならない。
ということが、ビョーンのバイブルの246ページに書いてある。
>209 現象っていうか文法を知らないだけではないかとjvんszぃ;vbds;pzvびsz@あvp
ビヨ〜ン
>>209 floatはコンパイラベンダのサービスだろw
// integral or enumertion typeのconstはinternal linkage
// 7.1.5.1.2より
未熟な質問者はすぐ切れます。
>>214 未熟な回答者もすぐ切れますが、これはどう説明する気ですか?
ちんことまんこが合体しているのです
>>214-215 未熟な自演はトリップの修正を忘れます。
>>209 >ということは、スコープをファイル内に限定する static const int hoge=3; と同じ意味になるのでしょうか?
>>210 が説明しているとおりだが、お前にわかりやすく言えば、次の2つは同じ意味。
const int hoge=3
static const int hoge=3 (規格的に正しいかどうか走らないがVS2005ではとおる)
>>218 ×正しいかどうか走らないが
○正しいかどうかは知らないが
const をa.c b.c 間で共有する場合、これで出来てるようであるが規格上はどうなの?
// a.c
extern const float aa = 10
// b.c
extern const float aa
constはデフォルトでは内部リンケージを持つけど、 externを付けると外部リンケージを持つ
>>220 うむ
だから
//file1
extern const int hoge = 7;
//file2
extern const int hoge = 8;
はリンクエラーだな
bcc32ではそうだった
ちなみに
//file1
extern const int hoge = 7;
//file2
const int hoge = 8;
も無問題だった
operator const char*() { return mpBuf; } これよく解らんのだが、どれが戻り値で、どれがオペレーターなの?
const char*がオペレータかつ戻り値の型
224 :
デフォルトの名無しさん :2006/07/22(土) 18:41:04
>222 C++は奇奇怪怪だなwww この書式にすぐにくじけてしまう
C++でゲームの作り方を勉強したいと思ってるんだけど、とりあえず はゲームを作ることを目的とした参考書じゃなくて普通の参考書を買っ て勉強したほうがいい?
void C( const char *_buffer ); なんて関数があった場合に、 そのOPが定義してあると、 Class class; C( class ); なんかで変換可能ってこと? こういうのなんていうの?自動型変換オペレーター?
PLC++3rdによれば、変換演算子(conversion operator)だそうな。
サンクス。 ぃぁーC++すごいわー・・・
231 :
204 :2006/07/22(土) 19:29:00
const についての質問をしたものです。色々お返事ありがとうございます。 実体が複数作られるのは避けたいため、extern 宣言をしようと思います。 // hoge.h (インクルードガード済み) extern const int HOGE = 3; struct HOGESTRUCT { int array[HOGE]; }; 今、このファイルを2つの cpp からインクルードすると、HOGE に関して重複定義のリンクエラーが起きました。 // hoge.h extern const int HOGE; のように、ヘッダ内では宣言だけにして、 // a.cpp const int HOGE = 3; のように、cpp 内で、HOGE の値を定義したのですが、 hoge.h のHOGESTRUCT の宣言時に HOGE の値が未知なため、array の宣言がうまく行きません。 extern をはずしてしまうと、HOGE の実体が複数作られておいしくありません。 これを解決するには、#define マクロを用いるか、enum ハックを行う、以外に方法はありませんでしょうか?
>231 >実体が複数作られるのは避けたいため なぜ? そもそもアドレス取らない限りコンパイル時に埋め込まれる。
>>231 常識的には
>>232 だが、それ以外でないとどうしてもいやだ、それをやると
明日首をつらなければならないって言うんならそんな奴には#defineがお似合いだ。
>>232-233 深い意味はありませんでした。複数作られることが単に無駄な気がしただけです。
例えば、10KB くらい分の定義が 100 ファイルから読まれると、1MB も無駄に exe が大きくなるんじゃないかなーと。
気にしないことにします。ありがとうございました。
>>234 >例えば、10KB くらい分の定義が 100 ファイルから読まれると、1MB も無駄に exe が大きくなるんじゃないかなーと。
普通その手のプログラムは実行モジュール自体が数100MBに達するだろうから無駄と言う観点では誤差。
#寧ろ他に減らすべきものがたくさんあるはずだ。
// hoge.h (インクルードガード済み) extern const int HOGE; struct HOGESTRUCT { int array[HOGE]; }; は明らかにコンパイルエラーだろう。extern const int HOGE;は外部変数を 参照するための宣言であって、int array[HOGE];のHOGEの定数値が定義されてない。 // hoge.h (インクルードガード済み) const int HOGE = 3; struct HOGESTRUCT { int array[HOGE]; }; ではだめなの?const int HOGE = 3;は内部リンケージを持つから、複数のcpp ファイルからインクルードしてもリンクエラーにはならないと思うけど。 認識違いだったらすみません。
>>234 >232
>そもそもアドレス取らない限りコンパイル時に埋め込まれる。
exeが大きくなることは無いって意味だとおもうが
const int HOGE = 3; は、アドレスを取らない限りは #define HOGE 3 とほぼ同じと思って構わない。 C++ では。
ifstream inf(argv[1]) ってな感じでコマンドラインで渡したパスを開こうとしても開けない 渡しているパスがC:\Programm Files\〜なんだけれども空白が原因? C:\test.txtは問題なかったし
>>240 空白で問題が発生するのは考えにくいな。
perror() してみるとなにかわかるかもしれない。
perror入れてみた 結果はNo such file or directory もちろんパスは実際にあるものを渡してるから無いはずはない 一応短いけどソース出しときます int main(int argc, char* argv[]) { //引数チェック if(argc!=2) return 0; printf("%s\n",argv[1]); ifstream inf(argv[1]); perror("test"); if(!inf) {/*・・・
>>240 × Programm Files
○ Program Files
ヲイヲイ、空白が原因に決まってるだろw 引数をダブルコーテーションで囲め
printf("%s\n",argv[1]);で正しい(と思ってる)パスが出てくるってことは
本当に
>>243 が原因なんじゃないだろうか
>>243-245 ごめんProgrammは素で間違えた
けれど引数の方はちゃんとProgramで渡してるから問題ない
ダブルクォーテーションもつけてて下の状態でも通らない
"C:\Program Files\JaneDoeView\Logs\Logs\2ch\PC等\プログラム\1048668198.dat"
>>246 いやその場合プログラム側でダブルクォーテーションを削除してからifstreamに渡さなければならない
>>246 × C:\Program Files\JaneDoeView\Logs\Logs\2ch\PC等\プログラム\1048668198.dat
○ C:\Program Files\JaneDoeView\Logs\2ch\PC等\プログラム\1048668198.dat
>>247 渡されたコマンドライン引数argv[1]をprintfで直接表示しても""はついてないから
それではないと思う
>>249 自分のだとlogs\logsの下にログがある
Jane入れたときに自分で設定を弄った
>>247 とんでもない嘘つくなよw
>>250 cmd.exeにargv[1]のファイルをD&Dして実行してみろ
>>251 C:\〜〜>"プログラム本体" "目的のdat"
やってみてもファイルオープンで躓く
fstreamに必要な設定とかあるの?
コマンドラインでなく直接パスを入れてみたら開くの? ifstream inf("C:\Program Files\JaneDoeView\Logs\Logs\2ch\PC等\プログラム\1048668198.dat");
どうせpermission deniedだろアホ
どうせ下らんオチなんだろ
かぶったw
>>253 ifstream inf("C:\\Program Files\\JaneDoeView\\Logs\\Logs\\2ch\\PC等\\プログラム\\1048668198.dat");
としてやってみてもNo such file or directoryで駄目だった
C:\abc def\ghi jkl\mno pqr.txt とかいうファイルを作って開いてみようとは思わんのか
notepad.exe C:\Prog〜 してみたら?
ところでコンパイラは何使ってるの?実は日本語がうまく通らないコンパイラだったり・・
>>260 メモ帳では開いた
>>261 タダで配布されてたVisualC++2005Expressつかってる
>>259 何故か思いつきもしなかった
"C:\\a s\\a s t\\a a.txt"でやってみたところどうしたわけか開いた
よく分からなかったんでレスつけられなかったけど
>>254 辺りが怪しいかもしれない
あまり長居すると悪いんであとは自分で調べてみる
ありがとう
JaneDoe起動しながらプログラム実行していたと仮定して。 JaneDoeにファイルへの排他的アクセス権を奪われているとか。
/dev/null や /dev/zero を表現したストリームって 用意されていないのでしょうか?
>>265 /dev/null はあるんでない nul
>>265 標準には無いね。 fstream で代用すれば?
/dev/nullpo ならあるよ。
/dev/ga お約束ですな
char *p = 〜 unsigned char *p = static_cast< unsigned char* >( c ); がエラーになるんですけど何ででしょうか? VS.net2003です。
271 :
269 :2006/07/23(日) 00:31:23
間違えました char *p じゃなくて char *c です
>>270 cがどこから来たか意味不明とか。
char*pとunsigned char*pで変数名の重複とか。
エラーメッセージ位かけよボケとか。
総じて意味不明
>>270 char*からunsigned char*への暗黙の型変換ができないから。
>>270 ちゃんとエラーの内容を書こうよ。答えがそのまま出てるから(笑
>test2.cpp(15) : error C2440: 'static_cast' : 'char *' から 'unsigned char *' に
>変換できません。
> 指示された型は関連がありません。変換には reinterpret_cast、C スタイル キ
>ャストまたは関数スタイルのキャストが必要です。
void hoge() throw() { foo(); // 例外を投げるかもしれない関数 } もしfoo()が例外を投げた場合の挙動は、どのように規定されているのでしょうか?
>>276 std::unexpected() が実行され、デフォルトでは terminate() に逝く。
vcでは例外指定は無効だけどね
いや、VC++でもthrow()だけは有効だった気がする。。
派生クラスにも基底クラスにも同名のメソッドがあります。 virtual メソッドではありません。派生クラスのなかから 基底クラスのメソッドを明示的に示して呼び出したいのですが どのようにすればよいのでしょうか? Java の super のようなキーワードに相当することを やりたいと思っています。
基底クラス名::メソッド名(...)
>>281 ありがとうございます。
なるほど、C++ では多重継承が許されているため
super というような記述は用意されていないのですね。
D&Eによると、inheritedというキーワードが提案されたが、 「自分でtypedefすればできる、だからこんなことでC++を肥大化させることないだろ」 ということになって、規格から外されたそうだ。 class foreman : public employee { typedef empolyee inherited; // ... void print(); }; class manager : public foreman { typedef foreman inherited; // ... void print(); }; void managaer::print() { inherited::print(); // ... }
また出たw はいはい、設計と進化最近よんだんでちゅね。 披露ご苦労さん。
しかも微妙に文意を間違えてるし。ダメだこいつ。
2chの夏、厨房の夏
知識厨ウザス
>>284 みたいに言いたくなるときがここ最近クソ多いが、
>>283 は知らなかったから今回はグッジョブと言いたい
と思ったけど、これが仮想関数だった場合問題になるんじゃねぇの?>inherited usingした方がいいような気がする
何いってんだお前。
質問者はちゃんと理解したのになw
gccだとthrow()指定してるときちんとアボートするけど vcはthrow指定しても普通にcatchに飛んで続行したよ
結論:VCは糞。GCCマンセー。
そもそもVCのthrow()は、最適化のためにあるだけだしな。
まあ微妙に標準規格からずれるのはMSのいつもの話だよね。 ただ、C++の例外指定はもう仕様に難があると思うし、きちんと 使ってる人もそんなにいるとも思えないしどうでもいいのかもね。
>>298 個人的にはいっそのこと廃止して欲しい。
そしたら throw を心置きなくマクロで弄れる。
(例外の発生箇所の__FILE__と__LINE__をログに吐ける。)
>>299 予約語をマクロで弄るのはヨクナイコトデスヨー
>>299 アドレスわかれば、どこか特定できるでしょ
>>300 そこが悩みの種
>>301 見ただけで分かる>>>>(越えられない壁)>>>>調べれば分かる
#define THROW ほにゃらら・・・・ でいいんじゃないの? throw そのままマクロにしなくても。
>>303 やっぱ、やるならそっちかなぁ。
ソース見てて頻繁に出現する俺マクロってなんかやなんだけどなぁ。
でも、他人の目から見てもコッソリ予約語が置換されるよりは
俺マクロが頻繁に出現するほうがまだましか。
>>300 うーん、俺も予約語がマクロで見えなくなるのはやだから結局
throw MyException(MY_EXCEPTION_INFO);
みたいな感じにしてるなあ。
ただ、やっぱスタックトレースで取れないとそこだけ情報取れても
役に立つことがあまりないかなあ。。
某ゲームのコードで全関数の最初と終わりにguard/unguardみたいに
仕込んでるのあったけど、あれもあれでちょっと問題あるし。
例外周りは悩みが尽きない。
>>183 「Containerに入れるには」、Assignableじゃないといけない。23.1.3
Assignableであるには、返り値の型は参照でないといけない。23.1.4
Effective C++ 34項後半に、ファクトリ関数なるものが紹介されています。 Person* pp = makePerson(...); // ppを使う delete pp; これは、makePersonにnewしてもらう一方で、呼出し側がdeleteする責任を負うので、 31項の教え「関数は、(中略)関数の中でnewで初期化したポインタの参照先を返してはならない」 に反する気がして、気になっています。 ・deleteの手間がかかるので、オブジェクトをnewして返すのは原則ダメ ・でもファクトリ関数として使うなら、やや危険だが便利なので気をつけて使え という解釈でいいのでしょうか?
簡単のためにそうした、という解釈は納得できない?
>>307 EffectiveC++の3版を読むといいと思うよ
>>307 参照返してないじゃん。
というか、
> ポインタの参照先を返
誤訳?
↑バカはスルー
例外使え使えって言われるけどエラー表示して終了するだけの コードしか見たことがない俺ガイル
例外がスルーされまくりなコードの保守をさせられたときがある。 五指に入るくらい最悪なコードだった。
>>312 俺もそんな使い方しかしていない。
下手したらcatchはmainの中だけ。
コンテナを内部に持つクラスを設計してるのですが、 インターフェースと実装を分けるべく、以下のようにしてみました。 趣旨は具体的に使用するコンテナを隠すことなのですが、 なんとなく※1の部分が気持ち悪いのです。 気持ち悪いという感覚は捨てていいのでしょうか?それともまずい設計でしょうか? ヘッダー class hoge { template <typename C> // Cはコンテナ型 class iterator_gen : public C::iterator { 適当な定義 }; class container; typedef iterator_gen<container> iterator; virtual iterator begin(void) = 0; virtual iterator end(void) = 0; }; 実装 class hoge_impl { class container : public vector<int> { 中身なし }; // ※1 iterator begin(void) { return m_cnt.begin(); } iterator end(void) { return m_cnt.end(); } private: container m_cnt; };
>>315 コンパイルできるんなら、いいんじゃない?
きっと iterator_gen の「適当な定義」が魔法みたいなコードなんだろう。
317 :
315 :2006/07/25(火) 03:47:41
>>316 どうも。
コンパイルできるという方針のみに従えば、大抵のコードはOKになってしまうと思います…。
他にこういうことしたことある人いないかなと。もしいなければなぜかなと。
> きっと iterator_gen の「適当な定義」が魔法みたいなコードなんだろう。
iterator_genはそんなに突飛なものではなくて、
↓みたいな適当なコンストラクタの定義と
typedef typename C::iterator base;
iterator(void) : base() {}
iterator(base_t i_) : base(i_) {}
あとはdereferenceやincrement演算を若干変更しているだけです。
>>317 それ、
hoge::iterator i;
って変数定義しようとしたら C::iterator の定義が要るだろ。
hoge_impl::container の定義が見えてるところじゃないと
コンパイルできないはずだが、それでいいの?
319 :
315 :2006/07/25(火) 05:00:54
っあーー。
>>318 さんの仰るとおりです。
実装部分だけテストしていてスルーしてました。
通りませんね。
// ヘッダー(hoge.h)
class hoge {
public:
template <typename C>
struct iterator_gen : public C::iterator {
typedef typename C::iterator base;
iterator_gen(void) : base() {}
iterator_gen(base i_) : base(i_) {}
};
class container;
typedef iterator_gen<container> iterator;
virtual iterator func(void) = 0;
static hoge* create(void);
};
// 実装(hoge_impl.cpp)
#include <vector>
#include "hoge.h"
class hoge::container : public std::vector<int> {};
class hoge_impl : public hoge {
public:
iterator func(void) { return m_cnt.begin(); }
std::vector<int> m_cnt;
};
hoge* hoge::create(void) { return new hoge_impl; }
320 :
315 :2006/07/25(火) 05:02:20
つづき // サンプル #include "hoge.h" int main(void) { hoge* p = hoge::create(); hoge::iterator i = p->func(); // ★当然通らない…★ return 0; }
321 :
315 :2006/07/25(火) 05:06:18
>>316 さんも
>>318 さんの指摘と同じだったのですね。恥ずかしい…。
ところでコンテナを実装に隠しながらイテレータを返すインターフェースを
実現する方法ってないもんでしょうか…。
>>321 仮想関数(みたいなの)使ったイテレータを自前で定義するしか無さそうだね。
一般的な設計の話にすれば、イテレータを使うような操作を
コンテナを持つクラスのメンバ関数にすることを先に検討するべき。
イテレータで可能な操作のすべてが必要なケースなんてあんまり無い。
323 :
315 :2006/07/25(火) 06:14:33
やっぱり自前定義しかないですよね。 class iterator { public: インターフェースいろいろ private: class iterator_impl; iterator_impl* m_impl; }; class iterator::iterator_impl : public 任意のコンテナ::iterator { 実装いろいろ }; みたいにするのが楽なのかなぁ。 > イテレータを使うような操作をコンテナを持つクラスのメンバ関数にすることを先に検討するべき。 なるほど。なんとなく理解できます。 でも今回はコンテナを内部に複数持つクラスを柔軟にSTLのアルゴリズム等に渡したいなぁと。 たとえば int xsum = std::accumulate(p->xbegin(),p->xend()); int ysum = std::accumulate(p->ybegin(),p->yend()); int zsum = std::accumulate(p->zbegin(),p->zend()); みたいに。
(機械的にできるという意味で)一番簡単なのは、 private継承して、メンバー関数を全部baseのメンバー関数を呼び出すように オーバーライドすることだろうけど、それでも百万年早そうだからあきらめろ。
325 :
307 :2006/07/25(火) 11:06:57
お返事ありがとうございます。
>>308 すみません、ちょっとよくわからないのですが、
「本当はいけないコーディングだけど、簡単にファクトリ関数を説明するためにそう書いた」
という意味でしょうか?
>>309 確かに私のは第2版でした。書き忘れてすみません。
今度本屋に行って読んでみます
逆アセするときどんなソフト使ってるか教えて
>>324 百万年早いなんて陳腐な表現平気で使うし
オマケに日本語間違ってるし
>>323 > でも今回はコンテナを内部に複数持つクラスを柔軟にSTLのアルゴリズム等に渡したいなぁと。
> たとえば
挙げられた例に説得力が無いな。
hoge に virtual int xsum() const; とか用意しろよ、と思ってしまう。
まぁうまく書き表せなかっただけなんだろうけど。
そもそもSTLのようなテンプレートをふんだんに使うコードと、 319がやろうとしている実装の分離とは相性が悪いから、 どこかで無理が出てきたり気持ち悪くなってくるのは仕方がない。 こういうときにboost::functionのイテレータ版があればいいなとは思う。 それがあったとしても、その実装は結局322が言っていることと同じことになるはずなんだけどね。
boost馬鹿
boost馬鹿の俺が来ましたよ。 iterator_facadeで一挙解決!
332 :
315 :2006/07/25(火) 16:04:01
>>324 結局全部(機械的に)書くことになるわけですね。
>>329 > そもそもSTLのようなテンプレートをふんだんに使うコードと、
> 319がやろうとしている実装の分離とは相性が悪いから、
それを痛感してます('A`)
インターフェイスとなる基本クラスXと実装X_impl、
Xの宣言をincludeしたテンプレートクラスX_tmpl(実装の大部分はX_implを流用)、
という構成を目指していたのですが、難しいです。
>>328 >挙げられた例に説得力が無いな。
はい…すみません。コンテナの中身はそれぞれ独自メソッドを持った自前クラスで、
シーケンシャルにコンテナ要素に対して特定の操作を行いたい、
かつその操作の種類を今後どんどん増やすという状況です。
public継承して、 隠したいところだけprivateで宣言しとけば? けどalgorithmを適用する時に面倒なことが起きがち。 特に名前ルックアップで
>>329 iterator のレベルの操作で実装を完全に隠蔽しようと(型を消そうと)すると,
たいていの場合効率の面で許容できない実装になるような気がします.
(例えば,ポインタのインクリメント1つに関数呼び出しが常に生じる)
それでも構わないというなら一応できなくはないと思います.
value_type (reference) の型情報はインタフェースの型安全性を支配するので
この型情報は消せないですが,それ以外の型を消去した
実行時多相のイテレータクラスは作成できるかと思います.
template< class Reference >
class any_iterator
{
......
};
などのような形で, Reference 型が一致する全てのイテレータ型を run-time で
多相的に扱えるようなイテレータクラスを作成できるかと思います.実装技術的には
広く Boost で使用されている Type Erasure という技術でできると思います.
ただ1点だけ難儀があるとすれば, operator==, operator!= などの2項の比較関数において,
異なるイテレータ型の間での inter-operability が存在するので,
厳密にこれ対処しようとすると run-time double dispatch をエミュレートしないといけない,
という問題はあるかと思います.
横から失礼
>>332 >結局全部(機械的に)書くことになるわけですね。
使うやつだけusingすれば?
iteratorはbaseのやつをtypedefでぱくっちゃうとか
336 :
315 :2006/07/25(火) 21:48:44
>>333 いずれにせよヘッダー内にコンテナが「見える」わけですね??
いえ…全然まずくないのですが。
>>334 > たいていの場合効率の面で許容できない実装になるような気がします.
そうですね…。仮想関数にせよハンドルを使うにせよ、
間接アクセスのコストがちょっと想像できません。
でも、なんとなくコンテナ要素に対する操作がボトルネックになりそうなので、
イテレートのオーバーヘッドは無視してもよさそうな気もしてます。
(そのおかげで気持ちよい実装になるならば、ですが)
Type Erasureもdouble dispatchも初見でした…。
Type Erasureというのはpimplをテンプレート化したみたいなものでしょうか。
double dispatchは相方の型がわからなくても、相方の仮想関数を使って
自分と比較すればOKということですね。スゴイですね…。
…あんまり頑張らなくていい気がしてきました(´・з・`)
>>335 そうする場合にはそういうことも含めていろいろありだと思います。
どうもでした!
iterator_facedeは検討しないの?
boost馬鹿の俺が来ましたよ。 iterator_facadeで一挙解決!
339 :
315 :2006/07/27(木) 09:45:25
iterator_facade、まだあんまり理解してませんが、 ちょろりと見た感じ「機械的に書く」ことを勝手にやってくれると理解しましたが…。 つまり表面を用意してはくれるけれど、中身(ポインタとか)はこちらで決めてくださいよと。 その中身に例えばコンテナのイテレータを使うとすれば、 結局コンテナが見えちゃうわけですよね。 うーん、何か勘違いしている気もしつつ…
iterater_facadeは最小限の記述でiteratorを生成してくれるので、 type erasureやpimplを使う時でも有効だと思います。
まだ勉強はじめたばっかりのものなんですが、 いまはVisualCでコンパイルしてるんですが、Linuxの環境でコンパイルすれば Linux用のソフトになるんですか?
>>341 互換性を意識して注意深くコーディングすれば可能。
hello world くらいなら全然OK。
レガシーなAPI hogeに出力引数としてvectorを渡しています void hoge(void* buf,size_t& written_size) vector<char> v; size_t written_size; v.resize(500);//500はAPI hogeが書き込む可能性のある最大の長さ hoge(&v[0],&written_size); このままだとvは自分の長さを知らないため、 v.resize(written_size); としているんですが、最後のresize()で 内部のバッファのアドレスが変わってしまう可能性はあるんでしょうか hogeが内部でバッファのアドレスを保持して使うので、 アドレスが変わってしまうとヤバスです 今のところ無事に動いてるのですが・・・ 最後のresizeで前の状態より長さが大きくなる事はないので 大丈夫かとは思うんですが 実装によりけり?
>>343 ヤバい予感。少なくとも標準では保証外。
§23.2.4.6
void resize(size_type sz, T c = T());
6 Effects:
if (sz > size())
insert(end(), sz-size(), c);
else if (sz < size())
erase(begin()+sz, end());
else
; //do nothing
§23.2.4.3.2
iterator erase(iterator position);
iterator erase(iterator first, iterator last);
3 Effects: Invalidates all the iterators and references after the point of the erase.
4 Complexity: The destructor of T is called the number of times equal to the number of the elements erased,
but the assignment operator of T is called the number of times equal to the number of elements in the
vector after the erased elements.
5 Throws: Nothing unless an exception is thrown by the copy constructor or assignment operator of T.
つーかresize()後にもっぺんポインタ取得しなおせばいいと思うんだが。
>>344 やはりですか。
eraseの呼び出しでポインタが無効化してしまう可能性があるという事すね
>>345 hoge関数は説明のために簡略化してますが、
hoge関数は内部で渡されたbufのアドレスを保持して、
後々別の関数で使ったりしているのです
素直にchar配列を使うべきかな・・・
>>346 つーか、なぜにresize()が必要なんだ?
仮想的なend()が欲しければ、v.begin() + written_sizeをv.end()の代わりに使えばいい。
v.size()が必要なら、writen_sizeを覚えておく……これは確かにあれか……。
ちうかまあ、その辺だとboostに転がってるスマートポインタ使ったほうがいいと思うが。
boost使うと変なおまけがいっぱいついてくるからやだ
>>344 > 3 Effects: Invalidates all the iterators and references after the point of the erase.
"after the point of the erase" ってことは、削除した場所より前は
大丈夫なんじゃないの?
352 :
351 :2006/07/28(金) 00:37:15
>>342 ありがとうございました。
Linuxにも興味があるので。
載ってるようにやってないから
-Wはどこいったの?
エラー E2075: コマンドライン オプションの間違い : -W -eRelease\win01.exe
全角スペース
>>358 あっできた・・・・どうもありがとうございます
ただでさえ遅いSTLのIteratorに仮想関数なんてつけたら 使い物にならなくなりそうだ。。 試してみたが、string::iteratorと生ポインタでは10倍くらい 速度が違うよ。
んなもの条件によって大きく変わる
1つの調査結果で解った気になる。 ゆとり世代にはよくあること。
メモリ操作とかの場合は効いてくるよ
適材適所 なんのためのマルチパラダイム言語なのかと
>適材適所 ま、そうだね。ディスクアクセスしてるときはiteratorが遅いなんて 計算量のオーダーが違うから問題にならないし。 ただ、もっとも下位のアルゴリズムライブラリはあらゆる使われ方を 想定して高速である義務があると思う。
計算量?
何の話やねん。
難しいことを書こうとして自爆した例
>368 かけたよ。でも、書き方によっては最適化されて消えてしまう場合も あるから難しいね。パフォーマンス測定のいい書き方あったら教えてくれ。 >366,369 あれ?なんか否定的?基礎ライブラリは速いほうがいいよねという普通の ことを言っただけのつもりだったが・・
ようは for(int j = 0; j < size; ++j){ と for(ite = s.begin(); ite != s.end(); ++ite){ これは結構差が出る。 operator++が動いてendでコピーコンストラクタが動いて・・だから
えー?
細かいけれど普通こうしませんか? ite pos = s.begin(); ite end = s.end(); for(; pos!=end; ++pos) {
std::stringの実装はstd::vector風だとは限らない。
でも、
for(int j = 0; j < size; ++j){
毎秒100回とかの処理(ディスクに書き込みとか)
}
for(ite = s.begin(); ite != s.end(); ++ite){
毎秒100回とかの処理(ディスクに書き込みとか)
}
とかは毎秒100回のオーダーが効いてくるからiteratorの遅さは
出てこない、というようなことを言いたかったのだが。
>>374 少なくともVCのstlは普通にoperator++が動いてendでコピー
コンストラクタが動くよ。xstringのソース見るとわかるけど普通に書いてる。
「コピー」コンストラクタじゃないだろ。
まぁ、 for (std::vector<int>::const_iterator it = v.begin(); it != v.end(); ++it) { sum += * it; } くらいなら for (int ic = 0; ic < end; ++ic) { sum += a[ic]; } と同じ程度のコードを吐くコンパイラくらいいくらでもあるだろ。
中途半端な知識の奴、ウザいぞ。
その辺のトレードオフをプログラマの裁量で 決定できるのがC++の魅力だと思います先生
>>375 >xstringのソース見るとわかるけど普通に書いてる。
なんだこいつ初心者か。「普通に書いてる」からなんだよバカが。
たとえソースコード上に書いてあったとしても、
最適化により、書いて無いのと同じ速度で動く可能性も知らんのか。
事実、以下のコードはまったく同じ速度で動いてる。vcでな。
まず最適化の掛け方勉強しとけ。
#include <string>
#include <numeric>
void test(){
std::string str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
int n = 10000000;
{
boost::timer t;
int sum = 0;
for(int i=0; i<n; ++i){
sum = std::accumulate(str.begin(), str.end(), sum);
}
printf("%d %g\n", sum, t.elapsed());
}
{
boost::timer t;
int sum = 0;
for(int i=0; i<n; ++i){
sum = std::accumulate(str.c_str(), str.c_str()+str.size(), sum);
}
printf("%d %g\n", sum, t.elapsed());
}
}
なんでキレてるんだ?
弱い犬ほどキャンキャン吼えるって言うしな
↑最適化の仕方もしらん糞の遠吠え
>>380 accumulateは
_Ty accumulate(_InIt _First, _InIt _Last, _Ty _Val)
{// return sum of _Val and all in [_First, _Last)
for (; _First != _Last; ++_First)
_Val = _Val + *_First;
return (_Val);
}
なので、380のコードはiteratorと生ポインタの比較にはなってないよ。
いいんだよ 「呼吸するようにboost使っててかっこいいですね」 とでも褒めておいて放置しとけ
>>384 は?どう見てもiteratorと生ポインタの比較になってるけど。
_InItの型が何になるか分からないの?
>>385 使えない劣等感を感じるぐらいなら勉強しろよ。
STLのイテレータって遅いんだろうか そりゃ生ポインタに比べれば遅いんだろうけど
同じだった、って書き込まれたすぐ後にコレだ
390 :
388 :2006/07/29(土) 23:10:44
いや最適化は考えない場合 ポインタに比べどういうオーバヘッドが生じるのかなと
>>390 最適か考えないんなら、ソース見ればわかるだろ。意味があるとは思わんが。
accumelateじゃなくってメモリへの代入とか比較とかの 場合に差がでるんじゃね? そっちでもっかいやってよ >> 380
boost馬鹿うぜえ
知識披露厨きんもーっ
これは ひどい
速度とか最適化とか考えると泥沼にはまるのもC++の仕様
試してみた #include <string> #include <windows.h> using namespace std; int main(){ strings; string::iterator ite; const int count = 1000000; const int size = 1000; DWORD start; int found = 0; for(int i = 0; i < size; ++i){ s += "a"; } // iterator書き込み start = GetTickCount(); for(int i = 0; i < count; ++i){ for(ite = s.begin(); ite != s.end(); ++ite){ *ite = 0; } } printf("iterator書き込み msec=%d\n", GetTickCount() - start);
続き // iterator検索 s[size - 1] = 'b'; found = 0; start = GetTickCount(); for(int i = 0; i < count; ++i){ for(ite = s.begin(); ite != s.end(); ++ite){ if(*ite == 'b'){ ++found; break; } } } printf("iterator検索 msec=%d, count=%d\n", GetTickCount() - start, found); // ポインタ書き込み char p[size]; start = GetTickCount(); for(int i = 0; i < count; ++i){ for(int j = 0; j < size; ++j){ p[j] = 'a'; } } printf("ポインタ書き込み msec=%d\n", GetTickCount() - start);
続き // ポインタ検索 p[size - 1] = 'b'; found = 0; start = GetTickCount(); for(int i = 0; i < count; ++i){ for(int j = 0; j < size; ++j){ if(p[j] == 'b'){ ++found; break; } } } printf("ポインタ検索 msec=%d, count=%d\n", GetTickCount() - start, found); }
もう続けなくていいぞ。
結果 iterator書き込み msec=3594 iterator検索 msec=4203 ポインタ書き込み msec=94 ポインタ検索 msec=1891 微妙にポインタの方が速いのかな。 あれ、でもポインタ書き込みは速すぎだな、最適化で飛ばされちゃったかな。 まあなんにしてもそれほど差はないのかな。
まともな考察もできないのに、ゴミコード貼る馬鹿
んじゃやって
やだもーん ぼくはやだもんねーだ
んじゃもういいや、iteratorは十分高速ということで終了
さすがC++だね
>>37 なぜ外で宣言する?
フツーこうだろ?
for(ite i = s.begin(), end = s.end(); i != end; ++i) {
どうでもいい
こうして、iteratorは遅いというアホな知識を得た人間が増えたのであった。
んなことない。 iteratorはちょーはえーが生ポインタと比べるともしかしたらちょっと くらい遅いかもねくらいでもういいよ。それ以上誰も証明できねーし。
iteratorが遅いと思うんなら生ポインタでalgorithm呼べばいいやん。 ちゃんとコンパイルできるんやし。
例えばstd::find()は自前のforループと同じコードに落とせるしね。
急激に糞スレ化が進んでいます。
仕様です。
>>398 なんでend()を終了判定のたびにコンストラクトしているんだ?
end()はconstじゃないぞ?
最適化したい奴はそうしろ。 保守性を重視したい奴はそうしろ。 ただし、富豪主義なんてプログラマの泣き言でしかないのを忘れるな。
個人を特定されかねない超訳単語のご利用はお控え下さい。
富豪とか、古くは大名とかって 一時期流行ったし、個人を特定するほど出はないと思うがなあ
俺も似たことしてみたがmemory上の検索でもほとんど差はでなかったね。 ただ、 for (ite = s.begin(); ite != s.end(); ++ite){ for (ite = s.begin(), end = s.end(); ite != end; ++ite){ は30%くらい差が出た。 アセンブリ見たら下の方がいいコードが吐かれたわ この程度最適化されると思ったが
>>422 それじゃ、end()の値が変動する可能性のあるコンテナには下の書き方は
使えないじゃん。
>>422 そういうことはコンパイラのバージョンと指定したオプションを明示した上で言ってくれ。
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86 オプションは/O2だけでいいな
>>424 何を当たり前の事を言ってるのだろうか。
>>427 いや、お前が低脳そうに見えたんで、一応書いておいたんだけどな。
どうせベンチマーク馬鹿だろうさ。 環境も明示せずに。
間抜けな
>>422 がいると聞いて、ぶっ飛んできました
432 :
デフォルトの名無しさん :2006/07/31(月) 18:56:45
>>424 もしかしてホンキでそれを言ってるのか…?
「end()の値が変動する可能性のあるコンテナ」があると聞いて飛んできました
ループ内でinsert()やったら平気でend()が変わるだろうが。糞が。
436 :
デフォルトの名無しさん :2006/07/31(月) 19:21:54
超初心者なんで、質問の仕方が悪いかもしれませんが教えて下さい。 配列変数がn種類あり、(array_1[]〜array_n[])これらの値ををそれぞれ、 n種類のファイル(file_1〜file_n)に書き込みたいです。 つまり、array_k[]の値を全てfile_kに書き込む。(ただし、k=0・・n) ここで、書き込むルーチンは全ての配列変数で同じことをやりたい。 従って、array_kをfile_kに書き込むルーチンを書けば、あとはkの値を1〜nまで繰り返せば良いと思うのですが、反復文を使って、変数名及びファイル名のみを変化させながら同じルーチンを繰り返す方法が分かりません。 ヒント:〜関数 といった程度で良いので、回答下さい!お礼は体で払います。
>>434 [begin, end) なループ内で insert なんかしたら、
end どころか、Iterator そのものが無効になる可能性があるだろ。
まさか、↓みたいなコーディングしてんのか?
for( iter it=c.begin(); it!=c.end(); ++it )
{
...
if( condition )
{
it = c.insert( it, newValue );
}
}
438 :
436 :2006/07/31(月) 19:28:44
例えば、 char array_1[] = "ちんこ", array_2[] = "まんこ", array_3[] ="アナル"; for (k = 1; k < 4; k++) cout << array_k << endl; とやっても、array_kを表示することをk=1〜3について繰り返すことになりませんよね。 こんな感じで、変数名・ファイル名だけ変えて同じ操作を繰り返したいんですが。。
>>436 ファイル名はstd::stringstreamで生成する。
後は、わかるな?
>>438 array_1は"array_1で"あって、数字部分は勝手に置き換えて考えられない。
k = 1 ・・・ n であろうと都合よく "array_k" みたく指定できないからね。
array[3][3]の2次元配列にすれば
for (int k = 1; k < 4; k++)
for (int j = 1; j < 4; j++)
cout << array[k][j] << endl;
で全要素を表示することならできる。
的外れだったらすまそ。
std::list<int> c; // ちょいと粋に1〜10までのコンテナを作る c.push_back(1); for(std::list<int>::iterator it = c.begin(), end = c.end(); it != end; ++it){ int last = c.back(); if(last<10) { c.push_back(last+1); if( end==c.end() ) std::cout << "ニヤニヤ" << std::endl; else std::cout << "ごめんなさい" << std::endl; } } まーコンテナの種類によりけり
>>437 std::listならそれもありかも……でもやりたいという場面が思いつかない。
443 :
436 :2006/07/31(月) 19:42:56
>>439-441 有難うございます!
変数に関しては、2次元の配列にすれば行けそうですね。
ファイル名に関してはstd::っての使えばいいんですか・・・
stad::ってのを見たことが未だないんですが、そこら辺勉強してみます。
>stad::ってのを見たことが未だないんですが 漏れもないな。
>443 ファイル名の生成は、別にCのsprintfでも良いけどな。 つか、いつになく初心者質問に優しいな。
>>437 なぜ「まさか」なのかわからんが、iteratorを引数に取る、破壊的なメソッドが
コンテナには用意されてるだろ。
そのときはいちいちend()を実行する必要があるというだけの話しだ。
>>442 なにかの条件でeraseするとか。
簡単な奴ならfor文じゃなくても書ける気がするけど、俺STLに詳しくないから知らない。
OSタンとかいるならコンテナタンがいてもいいよなと思いつつある俺ガイル 最近はgoogle::sparse_hash_mapタンにぞっこん
iteratorの実装をヘッダファイルで見てみりゃ、こんなアホなこと いう奴減ると思う
>>450 ヘッダファイルを自分で見て確認すること自体は俺もいいことだとは思うが、
それが規格で保証されていることと同列に扱われても困る。
>>448 std::remove_if
しかし、std::listには専用のlist::remove_ifがあるし、
vectorとかには、ひとつずつeraseするより、remove_ifしたあとにresizeするほうが効率的だし……。
remove→eraseじゃないの普通 そんな事してんの俺だけ?
shrink to fit
>>954 おっ
ER7035出たね
うちも出たんだがDVDインフォメーションセンターに問い合わせても分からず
工場だかに問い合わせてもらった結果、「普通は出ないはず」で
具体的な内容は客には伝えないことになってるって言われた
ひどい
(7000番台なのでHDD交換対応ではある)
456 :
455 :2006/07/31(月) 22:31:09
誤爆スマソ
ストリームへの浮動小数点でお聞きしたいことがあります。 3 1.5 10.4 4.88888 などを各行に一つずつ出力するときに、小数点の位置を そろえて出力したいのです。 3.00000 1.50000 10.40000 4.88888 のように小数部にパディングが入っても構いません。 setw や setprecision ではうまくいかないのですが、 何か他に使えるマニピュレータなど有りますでしょうか?
すみません、↑の書き込みですが、 先頭の空白が削られてしまいました。
std::ios::showpoint で行けそうな気がしてきました。
setwとsetprecisionで出来る
461 :
デフォルトの名無しさん :2006/08/01(火) 22:13:55
C++の標準ストリームの勉強ついでにカスタマイズをしています 流れとしては 1 basic_streambufを継承・・クラスhoge_streambuf 2 basic_streambufのメンバ関数overflowをオーバーライド←ここでストリームに何か書く 3 basic_iostreamを継承・・・クラスhoge_stream 4 クラスhoge_streamにメンバとしてクラスhoge_streambufを持たせる でとりあえず動いてはいるのですが、なぜ動いてるのか今いち理解できてません overflowはバッファが溢れた時に呼ばれるらしい事まではわかったのですが・・・ この辺りについて詳しく解説しているサイト等あったら教えてください
462 :
デフォルトの名無しさん :2006/08/01(火) 23:08:23
今まではCで書いていたのですが、最近C++に移行する必要が出てきました。 そこでC++でコードを書いてみたのですが、Cでほぼ同じものを書いた場合に比べて 実行速度が1/10くらいになってしまいました。 この現象について、何か心当たりのある方はいらっしゃいませんか? 中身のコードはほぼ一緒で、クラスを使ってみたという程度です。 アバウトな説明でもうしわけありません。
>>462 まあ普通に考えれば、ほぼ同じものを書いたつもりで、そうではなかったということじゃないかな。
「一時オブジェクト」できまくりなコードを書いてしまったとか。
実コードを晒せば、誰かがアドバイスしてくれるかもよ。
465 :
hehe :2006/08/01(火) 23:28:49
こんなクラスを書いた。 byte ClipToByte(int n) { if (n < 0) n = 0; else if (n > 255) n = 255; return byte(n); } class ColorRGB { private: byte _r, _g, _b; public: // コンストラクタなどは省略 int R(void) const { return _r; } int G(void) const { return _g; } int B(void) const { return _b; } int R(int r) { _r = ClipToByte(r); } int G(int g) { _g = ClipToByte(g); } int B(int b) { _b = ClipToByte(b); } }
466 :
hehe :2006/08/01(火) 23:29:46
これを使うと、 color.R( color.G() + color.B() ); のように書ける。 しかし、できれば、演算結果を次のように代入したい。 color.R() = color.G() + color.B(); こっちのほうが読みやすいし、書きやすい。 内部的には byte で保持しているので、次のようにはできない。 class ColorRGB { public: int& R(void) { return _r; } }
467 :
hehe :2006/08/01(火) 23:31:32
上記の記法をサポートするために、カラーの要素を読み書きするための プロキシ クラスを書いた。 class Color { private: byte _r; byte _g; byte _b; public: // コンストラクタとかは省略 class ConstRProxy { private: const Color* _color; void operator=(const ConstRProxy& lhs); public: ConstRProxy(const Color* color) : _color(color) {} ConstRProxy(ConstRProxy& lhs) : _color(lhs._color) {} operator int() const { return _color->_r; } };
468 :
hehe :2006/08/01(火) 23:32:50
class RProxy { private: Color* _color; void operator=(const RProxy& lhs); public: RProxy(Color* color) : _color(color) {} RProxy(RProxy& lhs) : _color(lhs._color) {} operator int() const { return _color->_r; } int operator=(int r) { return _color->_r = ClipToByte(r); } }; ConstRProxy R(void) const { return ConstRProxy(this); } // ConstGProxy G(void) const { return ConstGProxy(this); } // ConstBProxy B(void) const { return ConstBProxy(this); } RProxy R(void) { return RProxy(this); } // GProxy G(void) { return GProxy(this); } // BProxy B(void) { return BProxy(this); } };
469 :
hehe :2006/08/01(火) 23:34:19
このようにすると、次のような記述ができる。 Color color(10, 20, 30; byte r = color.R(); color.R() = color.G() + color.B(); しかし、この記法をサポートするためだけに、 こんなややこしいことをするのは、どうだろうか、と思う。 ご意見求む。
C++にはプロパティという概念が無いから、いちいちプロパティっぽいものを 実装すると、混沌とした状況に陥ると思う。
byte& R() {return _r;}のようにbyte&型を返すことにしてはではだめか? byteという内部実装を曝け出してしまうが、そこはトレードオフと言うことで勘弁。 そこはbyteをそのまま曝け出すのではなく、Colorのメンバとしてpublicにtypedefするということで我慢しろ。 また、プロキシを書くならもっと完璧を目指せ。 operator =はきちんと*thisを返すべき。複合代入演算子やインクリメント・デクリメントも当然設けろ。 その例では、メンバ関数へのconst修飾をきちんとすれば、ConstRproxyとRProxyに分ける必要は無いはず。 クラステンプレートを使えば、RGBのプロキシをまとめて書けるはず。
>>469 struct Color { byte r, g, b; };
>> 471, 472 要点は、byte 型の演算後に値をラウンドするのではなく、 自動的にクリップしたいということなんです。 足りないメンバ関数があったり、不完全な実装があるのは承知しています。 そこは本題ではないので、無視していただけると幸いです。
> メンバ関数へのconst修飾をきちんとすれば、ConstRproxyとRProxyに分ける必要は無いはず。 コンストラクタに const Color* を渡すか、Color* を渡すかを 切り替えないといけないので分けてあります。 > クラステンプレートを使えば、RGBのプロキシをまとめて書けるはず。 こちらはそのとおりですね。
>>473 class ClippedByte
{
public:
ClippedByte(int n) : clipped(ClipToByte(n)) {}
operator int () const { return clipped; }
private:
byte clipped;
};
struct Color { ClippedByte r, g, b; };
476 :
デフォルトの名無しさん :2006/08/02(水) 00:26:58
>>463-464 ありがとうございます!
参考に色々しらべてみたのですが、
>まあ普通に考えれば、ほぼ同じものを書いたつもりで、そうではなかったということじゃないかな。
が正解だったみたいです・・・お手数お掛けしました・・・。
ところで、一応速度的には向上したのですが、やはり遅いのは変わりません。
これは仕様ですか??
知らん。 君がどういうコードを書いているのかわからんし。
struct { struct { int a, b, c; } aaa[4]; } bbb; たとえばある構造体のメンバが別の構造体の配列(ここでは4つ)だけの場合でも、 上のように書かないといけないのでしょうか? それとも他のやりかたがあるんでしょうか。
struct { int a, b, c; } aaa[4]; でいいじゃん。
>>479 bbbが配列となった時のことを考えておりまして、
例えば bbb[2].aaa[1].a = 0;
のようにしようかと思ってたのですが、やはりおかしいですかね?
普通に二次元配列にして aaa[2][1].a = 0; とかでいいんでしょうか。
それとも使い方によるのですかね?
>>480 どっちでもいい。好きにしろ。何が聞きたいのかわからん。
亀レスだが、 lib.list.modifiers insert() Does not affect the validity of iterators and references.(略) lib.associative.reqmts 8 The insert members shall not affect the validity of iterators and reference to the container(略)
static変数を同一名で親・子クラス内でともに宣言して、 メンバ関数(親クラスで定義したもの)でその変数を扱う場合 例)CSuperClass.func(){ static_value = 0; } このメンバ関数を使うオブジェクトが親か子かによって 例でいうstatic_valueも親のもの、子のものにちゃんと振り分けられるのでしょうか それとも親クラスで宣言した関数内だから親のstatic_valueが使われるのかな
484 :
483 :2006/08/02(水) 02:42:58
↑間違えました ×CSuperClass.func() ○CSuperClass::func()
486 :
483 :2006/08/02(水) 02:59:49
>>485 なるほど・・・静的変数はクラスの恩恵はあまり受けられないってことですね
>486 恩恵とか意味が分からん。 子クラスに同じコードをコピペでもすれば?
488 :
483 :2006/08/02(水) 03:21:22
>>487 まったく同じ関数なのに、static変数を扱うせいで別に用意しなきゃならないのは
クラス継承のメリットの一部分を生かせないと思いまして
まあstatic変数とはそういうものだということは承知してますが
>>483 おそらく継承関係になってるのが設計ミスで
テンプレート+部分特殊化すべきクラスとみた
メンバ変数にすりゃいいじゃんと思ったのは俺だけ?
-1ってリテラルだっけ? それともリテラルの1に単項演算子の-がついてるの?
2.1.3.1 Integer literals [lex.icon] に符号はない。
2.1.3.3 Floating literals [lex.fon] には符号があるな。
496 :
デフォルトの名無しさん :2006/08/02(水) 22:55:00
C++でJavaのDIみたいなことができるライブラリみたいなものってありますか?
int a = 0xffffffffu; でaの値は処理系依存ですか?(intが32bitのとき)
498 :
デフォルトの名無しさん :2006/08/03(木) 01:05:13
>>497 4.7.3 より、整数から符号付整数への変換で、元の値が変換先の型で
表現できなければ、その値は処理系定義となる。
500 :
デフォルトの名無しさん :2006/08/03(木) 03:28:10
//vect.h template <class T> class vect{ T coord[3]; public: vect operator+(const vect &back)const; }; //vect.cpp #include "vect.h" template <class T> vect<T> vect<T>::operator+(const vect<T> &back)const{ ・・・ } という風に書き、main関数内でdouble型のインスタンスを二つ生成し、そのインスタンス同士を足して オペレーターを呼ぶようなソースを書くと、リンカが error LNK2019: 未解決の外部シンボル "public: class vect<double> __thiscall vect<double>::operator+(class vect<double> const &)const " (??H?$vector3d@N@@QBE?AV0@ABV0@@Z) が関数 _main で参照されました。 というエラーが出て実行できません コンパイルしたときはエラーも何もなく、どうしたらいいのかわからなくて困っています なにが原因だかわかりますでしょうか?
502 :
デフォルトの名無しさん :2006/08/03(木) 06:15:31
Windows によって iTraxx.exe でブレークポイントが発生しました。 ヒープが壊れていることが原因として考えられます。iTraxx.exe または読み込まれた DLL にバグがあります。 というエラーメッセージが出て困ってるのですが、何か心当たりはありませんか? 無視して継続すると、普通に処理ができます。
503 :
502 :2006/08/03(木) 06:17:30
HEAP[iTraxx.exe]: HEAP: Free Heap block 41c928 modified at 41caa8 after it was freed というのも書いてありました。
504 :
502 :2006/08/03(木) 06:46:19
すいません、自己解決しました。 メモリを確保していない領域に書き込んでしまっていたようです。 初歩的な問題で場を濁してすみませんでした。
505 :
500 :2006/08/03(木) 19:09:29
>>501 ありがとうございました
今後きちんとログを調べるようにします
506 :
デフォルトの名無しさん :2006/08/03(木) 19:10:39
クラスのインスタンスをスタック上に作成することは許可しますが、 ヒープ上に作成することは禁止したい。このようなことは可能ですか?
可能
508 :
506 :2006/08/03(木) 20:36:09
どうやってですか?
D&Eからだけど、こうするとグローバル変数とローカル変数しか作れなくなるそうだ。 class No_free_store { class Dummy { }; void* operator new(size_t, Dummy); // ... };
510 :
506 :2006/08/03(木) 21:42:51
>>509 ありがとう。試してみる。m(_ _)m
std::time_t がオーバーフローしそうです。
というかsizeof(std::time_t)は、 大きくなっている環境が増えてきているぜ?
514 :
デフォルトの名無しさん :2006/08/06(日) 14:14:36
冷害が発生した箇所を特定するにはどうすればよいでしょう? JavaやC#のように、スタックトレースの出力は行えないのでしょうか。
515 :
514 :2006/08/06(日) 14:15:13
平均気温と作況指数を見る。
517 :
516 :2006/08/06(日) 14:17:58
言葉が正しいかぐぐってる間に訂正された orz
今年のホットなテーマは冷害より雨害だと思うがなぁ。
冷害は常にクールな話題だぜ
>>514 自動的には行われない。自分で例外オブジェクトに __FILE__ とか __LINE__ とか
埋めれば、それっぽいことはできる。
処理系によるだろ。
>>514 マップファイルを出力しておけば、エラーダイアログに表示されるアドレスから、
どこで落ちたか特定できる。
>>521 例外オブジェクトのコンストラクタに毎回渡すってことか?
>>514 #ifdef NDEBUG
#define THROW throw
#else
#define THROW fprintf(stderr, "%s (%d)\n", __FILE__, __LINE__), throw
#endif
とかして、THROW を使えばいい。
このスレの 299- あたりも参照すべし。
530 :
524 :2006/08/06(日) 19:38:40
無視かよ・・・ orz
>>530 落ちた場所じゃなくて例外がスローされた場所の話だからね。
532 :
デフォルトの名無しさん :2006/08/06(日) 20:12:48
相談です。 Win2K, MSVC++6.0 以下のプログラムを実行すると unknown software exception(0xc00000fd) が発生して落ちてしまいます。 どこに問題があるのか分かる方お願いします。 #include <fstream> #include <iostream> int main(int argc, char* argv[]) { //test.txtは存在しています。内容に関わらずエラーが出ます。 std::ifstream fin("test.txt", std::ios::in | std::ios::binary); if(!fin){ return 0; } const int bufSize = 1024*1024; unsigned char buf[bufSize]; while(!fin.eof()) { std::cout << "r:"; int len = fin.read(reinterpret_cast<char*>(buf), bufSize).gcount(); std::cout << len << std::endl; } return 0; }
>>533 d。1MBは駄目でしたか。
スタックにバッファ取る場合は常識的にどれくらいまで可能可能なんでしょうか?
再帰などは無しとして100KBくらいでも大きすぎでしょうか?
知るかよ。 VC++のデフォルトは1MBだと思ったが。
>>535 C++ 処理系が満たすべき最低限の指標として、規格中に
> Size of an object [262 144].
というのがある。
移植性のためにも単一のオブジェクトサイズは
ここまでにしとくのがいいんじゃないかね?
スタックサイズという概念は規格には無いので、
実際のところは環境に合わせて考えないとだめだよ。
>>537 ありがとうございます。
最大でも200KBくらいということですね。
Linux+GCCでも使うので一般的なアプリの環境で考えていました。
ヒープに取れよ。newしろ。
>>537 早速誤解しやがったな。
"Size of an object" とスタックに確保可能なサイズは関係ない。
/Fオプションでスタックサイズを変更しろって。
100KBを超える場合はnewしようと思います。 コンパイルオプションを変えるほどの処理では無いので。 バッファは64KBにしました。
バッファ程度ならstaticにでもしてしまえばいいじゃん。
>>543 「バッファ程度」という基準の意味がわからん。 static のほうが嫌だし。
相手にすんなって。
546 :
デフォルトの名無しさん :2006/08/06(日) 23:25:45
初めて自分の家のPCでC言語を使ってみようと思って、NET Framework SDK をDLしてインストールしましたが、IIS(インターネントインフォメーションサービス)?が コントロールパネルのコンポーネントと追加の削除の中からできるようにしておかないと ダメみたいなので探しても見当たらない・・・。 これってもともとPCに入ってるものなの?? XPを使ってて他の方法も考えてますが誰かエロイ人教えてくれませんか?? お願いします><
教えてやりたいが俺はエロくないので…残念だ
他スレを見るまでもなくマルチと分かるこの香り
550 :
546 :2006/08/06(日) 23:35:58
これマジですorz マルチでもなんでもないんです!!(実はマルチの意味すら分かってない
551 :
549 :2006/08/06(日) 23:39:01
なんだよーマルチかよー 相手して損した
フーン
553 :
546 :2006/08/06(日) 23:44:18
>>549 ありがとう〜今やってるとこだけど俺は違うのを落としてたのかな?
ちなみにマルチってどういう意味?
マルチ商法??
>>553 複数のスレッドに同じ内容を書き込むこと。
それくらい自分で調べろよ。
555 :
546 :2006/08/06(日) 23:48:34
大丈夫!ここにしか書き込んでないから^^ ありがとう〜初心者なのでこれから頑張っていきます!!
556 :
546 :2006/08/07(月) 00:17:07
今やっと終わったけどIISって必要ないの? その部分に関しては何も変わってないきががする・・・
557 :
デフォルトの名無しさん :2006/08/07(月) 00:21:00
through
558 :
546 :2006/08/07(月) 00:21:48
through? 意味わかんないんだけど・・・
>>556 ドキュメント読んで一通りセットアップしてから、それでも問題が出たら VC スレに逝け。
560 :
546 :2006/08/07(月) 00:25:03
これってウィンドウズプログラム作れないの?
作れます。
562 :
546 :2006/08/07(月) 00:51:30
質問です。 class parents{...}; class child:public parents{...}; 以上の親クラスと、親を継承する子クラスがあったとして base *obj = new child; delete obj; このようにdeleteにポインタを渡す時点で型が変わってる時、 正常なdelete処理は行われますか? なんとなくparents型のサイズしか開放されない気がするのですが・・・。 教えて欲しいです。
555までで終わっておけば良かったのに
なんか損した気分
>>562 騙りレス番消し忘れてるぞ
>>563 問題ない。deleteは型の認識はせずにサイズだけ記憶している。
childのデストラクタにprintfでも仕込んで確かめりゃいいじゃん
カソーデストラーデ
568 :
563 :2006/08/07(月) 01:27:42
>>565 さん
ありがとうございます。メモリ自体は正常に破棄されるんですね。
>>566 さん
おっしゃるとおりです・・・ただデストラクタは呼ばれなかったけど
C言語のmallocとfreeなら正常に破棄してくれそうなので。
>>567 さん
仮想デストラクタの機能は今知りました!
まさにこういうのを求めてたので・・・ありがとうございました!
569 :
デフォルトの名無しさん :2006/08/07(月) 01:53:06
>>564 556までの間違いだろバカ!
なんか損した気分
バカは君のことだよ
バカばっかりだな
572 :
デフォルトの名無しさん :2006/08/07(月) 04:08:50
メモ帳で次の文字を教科書どおりに入力し、デスクトップに保存しました <HTML> <HEAD> <TITLE>Hello JavaScript</TITLE> </HEAD> <BODY> <SCRIPT language="JavaScript"> document.write("Hello! JavaScript!!"); </SCRIPT> </BODY> </HTML> IEで開こうとしてもなぜかHP調の画面にならず、そのまま文字が表示されるだけでした。これはなぜでしょうか? すみませんマルチになってしまい申し訳ありませんが
激しくスレ違い
574 :
デフォルトの名無しさん :2006/08/07(月) 06:18:26
int i; (i = 3) && printf("%d",i); これを一文で書きたくて ( int i = 3 ) && printf("%d",i); としたらiが定義されていないとエラーになります 一文では書けないのでしょうか?
無理。
変数の宣言は式ではないから、式の中には書けない。
gcc拡張に依存していいならブロック式が使える。 けどこれ結局、式文にして式の値使ってないから、 普通のブロックでも代りないのでは? { int i = 3; i && printf("%d",i); }
Perl だとできるんだよね。 my ($n) = /^(hoge)/ or die() まぁ、そもそも宣言しなくて変数使えるんだけど。
それがどうした。
アプリ上からchmファイルを呼ぶためには どのような記述をすればよいのでしょうか。 VC6.0です。
おーい、chmファイルやーい。
Perl だとできるんだよね。 ohi $file.chm or die() まぁ、そもそも呼ばなくてもchmファイルやってくるんだけど。
だからそれがどうした。スレ違いもいい所だ。
>>586 まぁまぁ。せっかく夏休みにPerl覚えたばっかりだから
ひけらかしたいんだろう。
>>585 そんなわけあるかw
だが、perlだとあっても不思議ではない気がするのが怖い。
>>575 int i = (((i = 3) && printf("%d", i)), i);
これで出来ないことはないが、こんなコードは採用するな。
>>589 それじゃ意味がちがくない?
というか、元々の文の意味も、何がやりたいのかよー分からんのだがな・・・。
i = 3 は常に真だから、
int i = 3;
printf("%d", i);
でいいじゃん。
>>589 >それじゃ意味がちがくない?
どのへんが?
>i = 3 は常に真だから、
わざわざ判定してるぐらいだからサンプルとして"3"を代入してるだけで
変わる可能性があるんじゃないのか?
プログラム初心者ですが、質問です。 例えば、プログラムA、プログラムBという、 VC++6.0できちんと動作する別々のプログラムがあったとして、 プログラムA上でプログラムBを呼び出し、(コマンドボタンなどで) 別窓で動かすにはどうしたら良いでしょうか。
無理
そもそもC++の規格にコマンドボタンというものは(ry
VC++6.0ということはWindows環境だと思うが、 Windowsの仕様にもコマンドボタンというものは(ry
597 :
デフォルトの名無しさん :2006/08/07(月) 22:42:10
VC8 on WindowsXPです。(環境依存の質問は良いでしょうか?) std::bad_alloc例外を投げてもワトソンがログ吐いてくれないのですが、 後でクラッシュした箇所を知ろうとしたときどうすればいいでしょうか。 クラッシュした直後であればクラッシュ報告ダイアログ上で情報が見られるようですが、 この情報はどこかに保存されていたりするのでしょうか…
>>591 >>それじゃ意味がちがくない?
>どのへんが?
i の値が保存されない
と思ったら、, i が最後に付いてたのね。 問題ないわ。スマソ。
int i = (((i = 3) && printf("%d", i)), i); を実行すると iの値は3
自己解決してやがるOTL
C++スレなんだからこれでいいじゃん if(int i = 3) printf("%d",i);
>>602 i のスコープがどーなるか知ってて言ってんのか?
VC6だったらどうなるんだろうな?w
>>601 すまんかった。
printf の ,i もあるから、それと勘違いしてたのね。
>>603 i のスコープはprintf()まで有効なんじゃねーの?
(if 文抜けたら無効)
>>610 禿とその仲間たちが int i = i; なんてエラーにしたほうがいいんだろうな、とか言ってる。
>>611 そのくせ void *p = &p; はおk、とか言ってるあたりがなんだかなぁもうって感じ。
確かにそうしたほうが非常に C++ っぽいとは思うが。
>>614 はぁ?それはOKに決まってるだろ。馬鹿ですぅかぁ?
int i = i; はiにどんな値が入るか完全に不定だが、 void *p = &p; はpにpへのポインタが入る。 なんだかなぁもうって言ってる人がなんだかなぁって感じ。 何にも分かってないんだね。
アホにつくレスだけは早いのなw
>>616 そんなことはわかった上で言ってるんだが。
脊髄のほうが早い。人間だもの。
>>618 ハイハイw 俺もお前が馬鹿と分かった上で言ってるよw
>>616 pへのポインタっつうことはポインタへのポインタってことなんすよね?
何か左辺と右辺で型が違うような気がする
分からんようになってきてもうた
void * だから何でも入るだろ。 まあ、void *p = &p; なんてすることに どれだけの意味があるのか知らんが。
#include <ctime> してるんですが、 time_t や time() がグローバルな名前空間に見えています。 std::time_t や std::time() じゃないと気持ち悪いのですが、 何とかなりませんでしょうか? ちなみに開発環境は Visual Studio 2005 Professional です。
std::string を関数の戻り値として使うときなどは、 中で激しくコピーが起こりまくっているんでしょうか? リファレンスカウントにするとか、copy-on-write に するとかは実装者依存なんですか?
>>625 RVOが働けば最低限のコピーでう済むだろうなあ。
リファレンスカウントとかは実装依存。
ふむぅ、RVOが働くかどうかも処理系依存だしなぁ。 std::wstring o(L"おなにぃ") //処理 return o; とかはやっぱやるべきじゃないんだろうか。 戻り値じゃなく参照な引数で返すべきなんだろうか。
ほかの参照ベースのオブジェクト処理言語系みたく 扱おうと思ったら、なんでもかんでも boost::shared_ptr ?
>>628 Boehm GCとかもある。shared_ptrなんかだと循環参照とか気にする必要がある。
>>631 寿命の問題が発生するのが嫌なんだろう。
嫌つーか、自動変数の参照返したらまずいだろ。
RVOって例えば以下で コピーコンストラクタが呼ばれなければ 効いているって考えていいんでしょうか? #include <iostream> using namespace std; struct A { A () {} A (const A &p) {cout << "hoge" << endl;} }; A func () {return A ();} int main () { A a (func ()); return 0; }
>>634 それだと func() の戻り値と a の生成で2回コピーコンストラクタが使われる可能性がある。
>>635 なるほど
hogeが表示される回数は0ないし1ないし2の可能性があって
何回呼ばれるかは規格では定まってないと.
勉強になりました.
637 :
592 :2006/08/08(火) 14:41:47
お答えくださったのに、何も言わずにすみませんでした。 お答えくださった方々、ありがとうございました。 スレが違っていたみたいです、申し訳ありません。 失礼しました。
639 :
デフォルトの名無しさん :2006/08/08(火) 18:06:17
クラスを定義すると無条件で(デフォルトで) 1)デフォルトコンストラクタ 2)コピーコンストラクタ 3)代入演算子 が生成されますか?
640 :
639 :2006/08/08(火) 18:13:03
何かコンストラクタを定義するとデフォルトコンストラクタは 自動定義されなくなりますが、コピーコンストラクタと代入演算子は あいかわらず自動で定義されたものがそのまま存在するのですね。 勝手に使われているのが不安な場合は両者を protected などに しておくというのが常套手段なんですか?
そんなあなるにboost::noncopyable
もう、boost禁止で。
643 :
あなる :2006/08/08(火) 20:22:37
>>640 代入演算子とコピーコンストラクタを、privateで宣言するのが常套手段。定義の必要はない。
何が何でもboost使いたければ、お好きなように。
ビットマスクって1と2が設定されているのと3が設定されているのはどうやって見分けるの?
>>645 どうやって見分けるかは完璧に君の自由だ羨ましいぜこのやろう
フラグの定数に3なんて使わないだろ
ブラク?部落?
1 2 4 8 16 32 64 128 256 512
1 & 2 のエイリアスとして3が定義されてるとか
1 | 2 じゃね?
STLのmapに抽象クラスって入りますか? 実際には、抽象クラスを継承したものを入れたいんですが。
>>654 なるほど。盲点でした。
ありがとうございました。
>>640 君、Effective C++読まないと!
ここって初心者スレだったの?
高度な話題になると荒れるから初心者でいんじゃね・・・。
>>638 遅レスでどうでもいいツッコミだが
「参照返す」って言われたら中で自動変数作って参照の戻り値を返す以外に
なんかあるか?
ある
T& foo() { return *(new T); }
勘弁してくれ
663 :
デフォルトの名無しさん :2006/08/09(水) 12:57:34
std::string& foo() { std::string *p = new std::string; ああだこうだ; return *p; } 普通にやる
665 :
デフォルトの名無しさん :2006/08/09(水) 13:24:23
その std::string のインスタンス、 ちゃんと責任もって delete してやれよ・・・
Effective C++によれば、
>>665 の意味でわけわからなくなるから、やらないこと推奨の方法。
string &a=foo(); のとき、 delete &a; ってなるのか? すごく気持ち悪いけど、よく使うやり方なのかな。 俺がもしどうしてもこういう場面になったらshared_ptr使うとおもうけど。
それ以前にあらかじめ引数でfooにstringくれてやれよ。
そんなあなるにmove_ptr
671 :
デフォルトの名無しさん :2006/08/09(水) 16:24:20
コンストラクタに与えるタグで振る舞いを変えたくて以下のようにしてみました。 ただ、継承しつつ内部に包含する(?)というのがある程度一般的になされることなのか 自信がありません。コメント頂けるとありがたいです。 struct base { virtual void func(void) = 0; }; // インターフェイス struct derived1 : public base { void func(void) { cout << "d1" << endl;} }; struct derived2 : public base { void func(void) { cout << "d2" << endl;} }; struct t1 {}; // 切り替え用の struct t2 {}; // タグ struct X : public base { X(t1) : m_impl(new derived1) {} // t1指定でderived1の動作 X(t2) : m_impl(new derived2) {} // t2指定でderived2の動作 ~X() { delete m_impl; } void func(void) { m_impl->func(); } base* m_impl; }; int main(void) { t2 t; // t2を X x(t); // 指定したので x.func(); // d2と表示 return 0; }
べつにふつーとおもた
673 :
671 :2006/08/09(水) 17:22:07
>>672 ふつーですか。
「インターフェイスの継承+包含による実装の委譲」と理解しました。
継承と委譲の関係を混同していたので気持ち悪く感じてしまったようです。
どうも〜。
>>673 デザインパターンのストラテジーパターンなどの説明を読むとすっきりするかもね。
tyr4w@hort5rs, 9yq@t@0w@deleteduese:joyw@rt?
structには、誰も突っ込まんのか
671でstructを使ったのはpublic:をけちって行数削減するためだろうと思ったが違うのか?
>>682 さあ?普段からstruct使う人かもよ?
684 :
671 :2006/08/09(水) 19:30:58
変なところを指摘されてる…。
structもclassも同じだと思ってましたがまずいですか?
structとした理由に
>>682 以上の意味はありませんが。
イッヨ 2chクオリティ
>>686 本質とは関係ないものを排除して、見やすくしてるんだよ。
その結果、本質とは関係ない疑問もわいたりするがな
無知な奴にしかわかないよ
>>671 コンストラクタの部分特殊化ができれば、
インスタンス作らないでもできるのにね。
>>676 同じような用途のiterator_categoryも、
ほとんどの場合struct使って書いてあるよ。
規格書からしてそうだから。
24.2 Header <iterator> synoposis
出た、規格書厨
structかclassか、typenameかclassかに突っ込む奴は素人
696 :
デフォルトの名無しさん :2006/08/10(木) 14:55:49
指定したフォルダ(ディレクトリ)以下のファイル名を取得したいのですが、 自分なりに調べたところ、VisualC++に依存したものしか見つかりませんでした。 出来ればWindowsでもUNIXでも使えるコードを書きたいのでVisualC++に依存した 物は作りたくありません。 STLやboostなどの(準)標準的なライブラリを使ってこういう事は実現出来ますか?
boost::filesystemでぐぐれ
boost馬鹿は新でいいよ。
new boost::馬鹿;
>>696 マジレスすると、ファイルシステムはOSによって異なるから、ディレクトリ操作は異なるAPIを使わざるを得ない。
それがいやなら、処理系依存部分をラップしてくれるライブラリを探してきて使う。
boost理解できなくて不貞腐れてるんだろ。
そうだね、boostは難しいもんね
>>702 どうやらboostが大嫌いな人が1人このスレに粘着してるみたい
無視していいよ
boost使わないまっとうなやり方を勧めないで、いきなりboost勧めるから嫌われる
使うだけなら簡単で便利だけど 理解しようとした途端に投げたくなるよね
こうやってboost無しではディレクトリエントリを読むこともできない 糞プログラマが誕生したのであった。
めでたしめでたし
>>706 まっとうなやり方って、autoconf使って場合わけとか?
>WindowsでもUNIXでも使えるコード これをするには、boostに限らずとも、 なんらかのクロスプラットフォームなラッパを使うしかないのだがな。 //! それとも、WindowsとUNIX両方のやり方を覚えてみる?
boost馬鹿馬鹿には何を言っても無駄。 ちまちま糞ラッパー書かせとけばいいんだよ。
boostって良いライブラリと思うけどね ところでどこが嫌いなの?
>>711 普通の人は、WindowsとUnixの両方のやり方を覚えるけど、それが何か?
とりあえずここは環境依存の話をしてよいスレではないはずだから、 WindowsとかUnix固有のやり方を答えるのは気が引ける。 逆に言えばそういう環境依存の答えを求めるなら、初心者歓迎のC/C++室で聞いてほしい。
ライブラリ依存の答えはOKなんだ。
Turbo C++復活だそうですね。
仕事でboostを使えない環境でやらなければならない可能性がある奴を除けば、 boostでいいだろ。 ただまぁ、Win32APIやUnixのシステムコールの使い方くらいは知っといても損はない。
>>713 仕事で使って好いときとイカンときがあること。
楽だから禁止のプロジェクトだと泣ける
>>719 それじゃboostのことは大好きなんじゃない?
嫌うべきは禁止するプロジェクトだよ
boost禁止されてる理由を言っていい範囲で教えてくれたらうれしい。
>>721 ソース納品の時の顧客の要望 orz
チームのレベル全体を見た時の上司の決定 orz
それだけに使えるときのありがたさときたら。
>>721 保障されていない外部ライブラリの使用を禁止される場合なんてざらだよ。
多分、反論したいと思うだろうけど、そういう場合が多いのが現実。
どうしてもそのまんまのソースでlコンパイル通したいなら boostだろうけど、普通はラッパ書くよなぁ。
「普通は」 特に根拠は示せないけど、自分の意見を通したい馬鹿が使う言葉 類似語 「一般的には」「常識では」「みんなもってるもん!」
「馬鹿」 社会不適合奢が好んで使う言葉。
>>727 「馬鹿」
自分が馬鹿な奴が使う言葉。賢い奴は他人に馬鹿と言わない。
>728はまず日本語をしっかり勉強しよう!
「社会不適合奢」 真の社会不適合奢が好んで使う言葉
>>730 本当に馬鹿だなぁお前。
728の何が図星当ててるレスだっていうのやら。
さっさと日本語勉強してこい。
残念。このレスを見た人は即死。
>>732 余程くやしいようですね( ´,_ゝ`)
そうだねw
お前ら「ラッパ」の使い方間違ってるぞ
露西亜を征服する意をこめて名付けられたんだそうな
738 :
デフォルトの名無しさん :2006/08/11(金) 04:48:17
組み込みとかの話を言い出すときりがないので それは置いといて、普段は仕事でも boost 使っているけど、 実行時型情報が使えない事情のあるプロジェクトで boost 禁止ってのがあった。 boots の中でも使ってもいいライブラリとそうでないモノを 分離すれば良かったんだろうけど、とりあえず面倒なので boost 禁止、と。
仕事ではよくあることだな、何の制約もないプロジェクトの方が珍しい STLでさえ禁止だったり、C++なのに一時変数は関数の先頭に必ず宣言をまとめろ、みたいな 規約(というか慣習)があるプロジェクトも多い品
>C++なのに一時変数は関数の先頭に必ず宣言をまとめろ これは普通だろ。
朝から釣りはいいよ暑苦しい
742 :
デフォルトの名無しさん :2006/08/11(金) 11:22:55
for_eachにテンプレート関数を渡したいのですがどうやればいいでしょうか。 以下のコードだと実体が無いのか未解決の外部シンボルを参照したとリンカに怒られました。 template <typename T> void NotOp(T& c) { c = ~c; } std::for_each(buf, bufend, NotOp<unsigned int>);
>>743 VC7.0(.NET 2002)です。
>>744 じゃ、たぶんバグだな。明示的インスタンス化を置いとけば一応動くはず。
こうだっけ?
template void NotOp(unsigned int&);
まぁバージョンアップをお勧めする。
いや、普通に通るけど?
>>746 バグって無いコンパイラなら普通に通るよ。
それとも VC7.0 でテストしてるってこと?
そういうこと。もっともbufとbufendの定義が書いてないから絶対とはいえんけど。
>>742 なんかあやしいから、コンパイルできて問題が再現する最小のコードと
エラーメッセージのコピペを貼ってほしい。
750 :
742 :2006/08/11(金) 12:17:45
今新しいプロジェクトを作ってみます。
#include "stdafx.h" #include <algorithm> template <typename T> void NotOp(T& c) { c = ~c; } int _tmain(int argc, _TCHAR* argv[]) { unsigned int buf[256]; std::for_each(buf, buf+256, NotOp<unsigned int>); return 0; } Linker error LNK2019: 未解決の外部シンボル "void __cdecl NotOp(unsigned int &)" (?NotOp@@YAXAAI@Z) が関数 _main で参照されました。 Linker fatal error LNK1120: 外部参照 1 が未解決です。 やはりエラーが出ます。
Academic Editionを買えるならAmazonで2005にしたほうがいいよ、安いし… 俺も2002愛用してたけど色々と諦めて2005にした。 インテリセンスが鈍い事以外に不満はなくなったよ
753 :
742 :2006/08/11(金) 12:47:32
やはりコンパイラのバグでしょうか。
とりあえず
>>745 氏の方法で回避したいと思います。
2005は余裕が有れば購入してみます。
回答してくださった皆様ありがとうございました。
1. プリコンパイル済みヘッダを使っているようだがstdafx.hには何が書いてあるのか。 2. TCHAR.hはどこでインクルードしているのか?というかこれMFCプロジェクト? 3. 1行目を削除してvsvars32.batからclだけでコンパイルしてみろ。
756 :
デフォルトの名無しさん :2006/08/11(金) 13:58:29
クラスで、コピーコンストラクタと代入演算子を明示的に定義せず、 コンパイラによって暗黙に生成されるものを使うほうが良い場合って ありますか?常に明示的に定義したほうがよいですか?
デフォルトの動作で問題ない場合は定義しなくていい。
758 :
デフォルトの名無しさん :2006/08/11(金) 14:12:04
>>757 「定義しなくていい」のか、「定義しないほうがいい」のか、どちらでしょうか?
物理的にはどっちでもいい。 スタンスだったら、人それぞれ。
760 :
デフォルトの名無しさん :2006/08/11(金) 14:15:14
明示的に定義しないほうが、コンパイラが最適なものを生成してくれる ということはないのですか?
知らんけどコンパイラによるんじゃないの? 俺は後で必要になるかもしれないから全部作ってるけど。 コンストラクタはメンバ初期化にも使えるから便利だし。 (初期化は代入よりも効率いいらしいよ)
762 :
L :2006/08/11(金) 14:58:17
読み込んだファイル(標準入力)内の単語の出現回数を数えて、 出現回数の略順にソートして表示するプログラムの場合で、 処理時間が最も短くできるのは何ですか?
std:::map
質問 ASP.NETでセッション作って、 ISAPIフィルタでセッションIDとか取得できる? ISAPIフィルタで認証ちっくなことしたい。
スレ違いだと思います 俺が答えられないのは内緒だぞ
ListViewItemのタグに数字のテキストを入れています。 string型の変数にそのタグのテキストを代入することはできたのですが、 それをintの変数に代入できません。(下の式) 初歩的な質問で申し訳ないですが、ヒントで結構ですので 教えていただけませんでしょうか? private void btnApply_Click(object sender, EventArgs e) { foreach (ListViewItem itm in lvwSkillTable.CheckedItems) { int tagNum; if (itm.Checked) tagNum = Convert.ToInt16(itm.Tag.ToString()); if (tagNum = 77) MessageBox.Show("できた"); //intに変換できたか確認 } }
↑誤爆しました。無視してください。
>>766 それは C++ じゃないので、まずは自分の使用している言語を確かめて、
適切な別のスレを探してください。
脊髄反射失敗恥ずかしい
それ脚気やんビタミンB1補給しろ
771 :
デフォルトの名無しさん :2006/08/12(土) 13:54:06
boost::filesystemは、TR2に入るんで、 C++0xでは標準になる可能性大です。
boostが標準になったときは名前空間はどうなるの? 「boost::→std::」になるのはどうもやだな
じゃあ boostd:: で。
C++でHibernateみたいなことできますか?
>>775 ”C++ ORM”で調べるくらいのことはしましょうぜ
>>506 の逆はできますか?
クラスのインスタンスを、ヒープ上には作成できるけど、
スタック上には作成できないようにしたいです。
コンストラクタをprivateにすればいいのかなと思いましたがnewもできなくなるみたいですね。
今はnewInstanceというクラスメソッドを作ってそこから生成していますが、
出来れば、ClassName::newInstance()という記述が嫌なので、
new ClassNameと書ければいいかと思っているのですが。
>>777 小汚いテクニックを使えばできんこともないだろうけど、
いまのやり方のままのほうがええよ。
779 :
アナルロックオン :2006/08/13(日) 17:33:57
>>777 コンストラクタを隠蔽してファクトリメソッドを使うところまでは良し。
で、後は new 演算子をオーバーロードすればいいんじゃね?
autoconfを使えるようにしようと下のサイト
ttp://www.ogis-ri.co.jp/otc/hiroba/technical/CppUnit/chapter3.html のサンプルを試しています。
automakeがinstall-shをconfig以下に作るのはいいのですけどconfigure
の方のac_aux_dirが空のままで./configureを実行すると
configure: error: cannot find install-sh or install.sh in . ./.. ./../..
となってMakefileが作られません。
aclocal --acdir=configも試したのですが
aclocal: configure.ac: 6: macro `AM_INIT_AUTOMAKE' not found in library
となってしまいます。今使っているのはautoconf 2.5xなのでサンプル
通りにはいかないのでしょうか?
configureでac_aux_dir=configと手動で設定してやれば./configureは
成功するのですが自動生成する方法はないでしょうか?
>>777 Effective C++の第八章(第三版で)「newとdeleteのカスタマイズ」は読んだ?
>>781 あちらは過疎ぎみだったのでこちらに書き込みさせて頂いたしだいです。
マルチポストになってしまった。
あーらら じゃぁどっちでもスルーだね
785 :
777 :2006/08/14(月) 01:10:00
>>778 名前が長いのが嫌っていうだけなので、小汚いテクニックとなるならば今のままにしておきます。
>>779 オーバロード!?すれば出来そうなのですか?ちょっと調べてみます。
>>782 えっ!?その手のネタが書いてありました!?読み直してみます。
あっ。ウチにあるの第2版でした。
2版でもnewのオーバーロード書いてるだろ
質問、こんなことできたっけ? void proc(int iLen) {
、、ミスった、、質問、こんなことできたっけ? void proc(int iLen) { char buf[iLen]; ← これ ・・・・ } gccや、C99で可とか教えてほしいです
>>788 c99で可。
今のgccはc99対応なので勿論可。
実装はalloca()相当を使うからスタックサイズに注意。
>>789 即レスサンクス
c99なのか、寝る前に分かって良かった、ありがとう
なんで、ifstreamの>>オペレータでunsigned shortの実装がないんじゃーーーー。 WORDが読めないジャン。。。 readはchar*かwchar_t*のどっちかしかないし。キャストすんのきもいよー。 なんか解決策ありませんか?
union{ int i; WORD w; };
>>792 はや!レスサンキュー!!
そういう方法になるのかー。うーん。
DWORD の場合はどうしますか?(32bit符号なし整数の場合。intも32bit)
union { unsigned long ul; DWORD dw; };
>>791 それはどこの処理系?
それはともかく自分でグローバルな関数を作ればよいだけでは?やや面倒かもしれないけど。
template <...>
std::basic_istream<...> operator >>(std::basic_istream<...>, unsigned short&);
std::operator>>をオーバーロードすりゃ良いじゃん まぁ、微妙に標準やぶることになるけど気にしない。
>>794-796 レスサンキュー。
VC2005EEなんだけど、どうやらunsignedの>>オペレータはどれも無いみたい。あとint64関連も無いみたい。
オペレータオーバーロードはいいけど、ちゃんとsignedで読んでunsignedに代入で反映されるかちょっと不安です。。。
補数とかそういうのあんまり詳しくないんです(汗
*余談*
ビットマップの汎用クラス作ってるんだけど、
構造体のアラインメント関係でガーっと読んでっていうのができない(処理系に依存する)から要素を一個ずつ読んでるのです。
まーこの際そんなこといってる場合じゃないかもしれないけど・・・。
798 :
デフォルトの名無しさん :2006/08/14(月) 22:42:53
ちらっとallocaの話題出たけど、例外を投げる関数でそれ使っても安全? allocaとva_argsと例外とsetjmpとWIN構造化例外って排他的関係にならないの?
>>798 例外を受け取るときには使えないようだが、ほかは問題なさそう。
http://msdn2.microsoft.com/ja-jp/library/wb1s57t5.aspx 排他的関係というのは無いと思う。
allocaとva_argsはスタックの大きさが可変になるだけで特に不都合は考えられない。
VC++なんかだとC++例外処理にはWindowsの構造化例外処理(SEH)を使っている。
Windowsの構造化例外処理(SEH)はsetjmpなんかにも対応している。
たとえばVC++ではコンパイラオプションでSEHを使うよう指定したら、
setjmpでもローカルオブジェクトのデストラクタが呼び出されるようになる。
よそのスレへ行くべきだな、すまん。
>>797 > VC2005EEなんだけど、どうやらunsignedの>>オペレータはどれも無いみたい。
氏ねや、MS。
>>798 alloca()は標準じゃないので、コンパイラのマニュアル読んでください。
一般的なalloca()の実装では、例外で外に出て、問題ないはずです。
>>798 va_args は実際に問題が起きることはないだろうが、
va_end が呼ばれないままになる場合は問題が起きても文句は言えない。
>>799 レスサンキュー。
・・・あれ?ほんとだ。あるなー。
・・・あれ?コンパイル普通に通った。
さっきの格闘はどこへ??
あっれーーーーー!? XP
ごめん。勘違いだった。
ほんとにごめんなさい。
805 :
デフォルトの名無しさん :2006/08/15(火) 17:53:46
質問です。 void func(const hoge& i=0) { // 参照を引数にして if (i!=0) i.huga(); // 引数が渡された場合に実行 } ↑こういうことしたいのですが、引数がポインタなら問題ないのですが、 参照の場合operator!=()を定義しないと駄目ですよね。 そこまでするのは大袈裟なので、参照を使いつつ、 簡単に書くお約束の方法があれば知りたいのですが…。 何かいい方法はありますでしょうか。
>>806 どうも。実は
func();
func(const hoge&);
という関数が無茶苦茶たくさんあって、
オーバーロードするとコードサイズが倍になってしまうんです。
二つのfunc()が同じ事をするなら、引数が0なら渡されていないと考えていいのなら func(){ func(0) ; } func(const hoge & i ) { if (i != 0) i.huga() ; }
戻り値の型忘れたけど、重要じゃないか。
812 :
809 :2006/08/15(火) 18:38:23
あ、ほんとだ。スマソ
func(){実装} func(const hoge & i ) { if (i != 0) i.huga() ; func (); } じゃない?
814 :
813 :2006/08/15(火) 18:40:55
ゴメン ifはいらね func(const hoge & i ) { i.huga() ; func (); }
>>813 どうも。結局func()とfunc(const hoge&)の両方必要なのは変わらず、
という感じでしょうか(実装部の流用はできますが)。
諦めて全部書こうかな…。
関数宣言が引数やテンプレートの特殊化の組み合わせですごい数に…。
テンプレート引数a種類×関数b種類×…×コンストラクタ引数z種類=('A`)
規則性があるならコードを吐くプログラムを書いてみるとか
>>815 コンストラクタが関わってくる理由がわからない。
>>817 何言ってるんですか?頭大丈夫ですか?
とても心配です。お便り待ってます。
>>817 あぁ、
>>815 は少し変な書き方でした。すみません。
上でfuncとしていたのは全部コンストラクタです。
仮想コンストラクタにしているので
struct hoge1 {
template <typename T> hoge* create(引数リストA);
template <typename T> hoge* create(引数リストB);
template <typename T> hoge* create(引数リストC);
};
struct hoge2 {...};
struct hoge3 {...};
...
みたいになるということです。
デフォルトの引数で多少なりとも量を減らせるかなと思った次第。
>>805 俺だったらこーする。
void func(const hoge &i = *(const hoge*)NULL) {
if (&i) i.huga();
}
参照の実装は結局ポインタだからな。
821 :
805 :2006/08/15(火) 19:30:33
>>820 ファイナルアンサーの予感!!
どうもありがとう。
それって規格的に駄目じゃなかったっけ?
最悪な解法だけど、納得したということで。じゃ次。
824 :
805 :2006/08/15(火) 19:53:50
エー('A`)
ていうか引数が参照じゃないと駄目な理由が解らん。ポインタでいいじゃん。
何が必死なんだ?見当違いの煽りをするな。
つい最近必死だなとかって煽られて、悔しい思いでもしたんじゃないの?
830 :
805 :2006/08/15(火) 20:57:58
結局ポインタで実装しました。
んー、参照に未練…。
>>826 参照だと
struct mypred { bool operator()() ... ; } };
func(mypred());
って出来るのがうれしい…。
>>830 流れを読まないでレス。
それってポインタならfunc(& mypred());って話?
#中身見てないから意味があるのか知らんけど。
833 :
デフォルトの名無しさん :2006/08/16(水) 07:52:17
ifstreamで以下のチェックをパスするのに、>>演算子で値が取得できない場合ってどんな状況ですか? if(ifs.is_open() == false) return false; if(ifs.fail()) return false; if(ifs.good() == false) return false; if(ifs.bad() == true) return false; if(ifs.eof()) return false; std::ios::iostate state=ifs.rdstate(); if(!(state == std::ios::goodbit)) return false;
素朴な疑問、それらのチェックは動的なのか? 直前の読み込みなどの結果を反映する静的なものということはないか?
>>834 レスthx
えーっと、>>演算子の後にチェックをかけたら、エラーを返しました。
チェックのやり方がまずかったみたいです。おかげで何とかなりそうです。
ありがとうです。
つーかさ、stdioのfeof()等もそうだけど この手のって、実際に読んでみてから 「読んでみたらエラーだった」「読んでみたらEOFだった」しか わからないだろ。 で、その結果に応じてフラグを設定するんだから。 いや、ライブラリに限らず、OSのファイルアクセスだってそういう仕組みだし。
いわれてみればそうですね。うーん。
読んだけどヤだったから読まなかったことにします! なんてのもあるよな。
いやな理由がちょっと思いつきません。 まさか、実装してないとかそういうことじゃないだろうし。うーん。
アルファベットなのにintで読もうとした、とか。
アルファベット? 漢字なら良かったか?
>>832 それだと「一次変数のアドレスを渡そうとしてる」って警告が出ます。
>>843 標準でもconst参照は右辺値で初期化できるから、警告になるわけがない。
845 :
843 :2006/08/16(水) 12:39:04
あ、なるほど、ただの参照じゃなくてconst参照だったか。ちゃんと遡ってみるべきだったな。
>>840 あ!それです!!たぶん。
やっとわかった。(TT;
大分投げやりになってたとこです。
レスが遅くなって申し訳ない。
ありがとうございました。
いた違いだったらすいません CentOSを使ってC++のプログラミングの勉強をしています 今、mainを書いたファイルとは別にclassを書いた二つのソースを作って、分割コンパイルしてみようと思ったのですが、やり方がさっぱりわかりません 分割コンパイルのやり方はいろんなサイトに乗っているのですが、こういったclassを丸ごと別のソースにするやり方がどこにも書いてないので、困っています やり方をご存知の方は教えていただけませんでしょうか? あと、ひょっとしてこういうプログラムの書き方って普通しないものなんでしょうか?
>>847 やりたいことは、まぁわかった。
あとは、自分でやったことと、その結果(エラーメッセージとか)を
書いてもらわないと話にならん。
foo.h: class Foo {} foo.cpp: Fooの実装 bar.h: clas Bar{} bar.cpp: Barの実装 main.cpp: #include "foo.h" #include "bar.h" $ g++ -c foo.cpp $ g++ -c bar.cpp $ g++ -c main.cpp $ g++ -o hoge foo.o bar.o main.o あるいは $ g++ -o hoge foo.cpp bar.cpp main.cpp 普通はMakefile書くね。
Makefile: all: hoge hoge: main.o foo.o bar.o [TAB]g++ -o $@ $? main.o: main.cpp foo.h bar.h foo.o: foo.cpp foo.h bar.o: bar.cpp bar.h [TAB]のところはTABキーでインデント。
>849 あのものすごいバカな質問してしまうかもしれませんが教えてください foo.cpp の実装ってなんなんでしょうか? foo.hに class foo{ int x; foo(){ x = 1; } } とか書くとして、foo.cppには何を書けばいいんでしょうか?
>>851 それで終わりなら foo.cpp 要らない。
>>851 分割コンパイルの目的からすれば foo.h で foo(); と宣言だけで済ませて、
foo.cpp で foo::foo() { ... } と(実装を加えて)定義する。
>>851 以下のようにメンバ関数の定義を別ファイルでやる場合に*.cppが必要になる。
こうするとなぜ良いのかというと、class Fooの内容(実装詳細とかいう)が変わっても、
foo.hをincludeしているソースをコンパイルしなくても済むため。
foo.h:
class Foo {
public:
Foo() {}
virtual ~Foo() {}
int open(void);
int close(void);
};
foo.cpp:
int Foo::open(void)
{
}
int Foo::close(void)
{
}
コンパイルとリンクの違いは分かってる?
>852-854 言われたとおりやってみたら、.oファイルは作成できましたが、リンクが上手くできませんでした エラーがあまりに大量にでているので、全部は書けませんが GUI.o(.text+0x202): In function `GUI::~GUI()': : undefined reference to `XCloseDisplay' のようなものが大量に出ています コンパイルの仕方に問題があるのでしょうか? mpiとX Windowを使うので mpicxx -o -lX11 -L/usr/X11R6/lib main.o GUI.o としてコンパイルしてみたのですが・・・
>>856 ライブラリの指定を最後にしてみろ。
こっから先は別スレでやってくれ。 gcc スレでいいんじゃないかな?
下記のコードのようなことがやりたい (標準出力またはファイルのいずれかを実行時に 選択して、あれこれ書き込みたい) のですが、コンパイルエラーが出ます。ストリーム は複製できない、というのが理由だと思うのですが、かといって s2() から auto 変数 への参照を返すこともできないし… (Java なら GC されるまでストリームが消えない ので平気なのですが)。どうするのがよいのでしょう? #include <cstdlib> #include <ctime> #include <fstream> #include <iostream> using namespace std; ostream s1() { return cout; } ostream s2() { return ofstream("foo.log"); } int main() { srand(time(NULL)); ostream out(rand() % 2 == 0 ? s1() : s2()); out << "foo" << endl; out << "bar" << endl; // and more... return 0; }
860 :
859 :2006/08/17(木) 17:17:59
エラーの内容: foo.cc: In copy constructor `std::basic_ios<char, std::char_traits<char> >::basic_ios(const std::basic_ios<char, std::char_traits<char> >&)': /usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/ios_base.h:781: error: `std::ios_base::ios_base(const std::ios_base&)' is private foo.cc:7: error: within this context foo.cc: In copy constructor `std::basic_filebuf<char, std::char_traits<char> >::basic_filebuf(const std::basic_filebuf<char, std::char_traits<char> >&)': /usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/streambuf:769: error: `std::basic_streambuf<_CharT, _Traits>::basic_streambuf(const std::basic_streambuf<_CharT, _Traits>&) [with _CharT = char, _Traits = std::char_traits<char>]' is private foo.cc:8: error: within this context
newすればいいとおもうよ std::ostream* out = argc > 1 ? new std::ofstream( argv[1] ): new std::ostream( std::cout.rdbuf() ); *out << "foo" << std::endl; // and more delete out;
862 :
859 :2006/08/17(木) 17:30:03
>>861 うはー…なるほど、そんな手が。
お早い回答、本当にありがとうございました。
VIPPERに好かれて困っています
http://ex16.2ch.net/test/read.cgi/news4vip/1155903854/ >>1 (巨乳・ナンパ多し) 会社の先輩
年齢:23歳 年齢:33歳 ♂
彼氏いない暦:半年 彼女いない暦:恐らく年齢
身長:158a 身長:160cmくらい
体重:51` 体重:80`くらい
先輩は
>>1 がVIPPERとは知らない
Sサイズのシャツから肉がはみ出てる
変にオサレぶってかっこつけてキモイ。
でもオバサマには人気ある
上司とすげー仲良い(信頼されてる)
メールの内容
「今日は楽しかったおo(^ω^)o 注)一緒に帰っただけ
また月曜に会おうNe星
ちゃんとお風呂入るんだおwwwww」
「俺はインターネッツに詳しい」と豪語(ry
会社が終わるとロッカー前で毎日待ち伏せ
→同じ路線なので着いてこられる
→「本屋に寄るから」と断ると一緒に来る
→「今度一緒に映画行こうか(^ω^)」
→断ると以下ループ
864 :
デフォルトの名無しさん :2006/08/19(土) 13:14:49
#include <iostream> #include <fstream> using namespace std; int main () { int length; char * buffer; ifstream is; is.open ("test.txt", ios::binary ); // get length of file: is.seekg (0, ios::end); length = is.tellg(); is.seekg (0, ios::beg); // allocate memory: buffer = new char [length]; // read data as a block: is.read (buffer,length); is.close(); cout.write (buffer,length); return 0; } このコードで5Gくらいのファイルを読むと処理に時間がかかるんですが どういった方法で読み込んで処理すればよいでしょうか?
>>864 速度はきわめて環境に依存するので各環境スレへどうぞ。
#その場合、OS、コンパイラ、CPU、ディスクなどの情報も忘れずに。
目安としては、そのファイルをできる限りシンプルな方法でコピーしてみて
その所要時間より速くはできないと思っておけばいい。
ありがとうございます。一行ずつとかで処理かそんな感じなんですね・・・
id<T>::resultがT::resultと同じ型になるテンプレートクラスを作りたいんですが, template<class x> struct id{ typedef x::result result; }; とすると宣言するだけで warning C4346: 'x::result' : 依存名は型ではありません。 error C2146: 構文エラー : ';' が、識別子 'result' の前に必要です。 error C2501: 'id<x>::result' : 識別名を宣言するのに、型が指定されていません。 とエラーになってしまいます.(VC) どうすればよいでしょうか.
>>867 コンパイラはx::resultが型かどうかわからない。
テンプレートの初歩からやり直すべき。
template < typename T >
struct id
{
typedef typename T::result result ;
} ;
>>869 ありがとうございます.解決しました.
初歩からやり直してきます…
basic_stringのc_str()とdata()の違いはなんでしょうか? どちらも同じ物が返ってるようなのですが。
c_strは\0で終わってるけど、 dataは\0で終わってるとは限らない。
874 :
デフォルトの名無しさん :2006/08/19(土) 16:39:35
おまえらよぉ 毎日シコシコとコンピュータばっかいじってないで、お外に出て遊べよ おれはこの真夏の光の中を走ってきたぜ
仕事が忙しいっつーの
このコードはコンパイルできないんですが何がいけないんでしょうか? void print()の行をぬくとコンパイルできます。 #include <iostream> using namespace std; class Entry { public: Entry(string& name) { theName = name; } void print() { cout << theName << endl; } private: string theName; }; int main() { return 0; }
ちなみにエラーの内容は error C2679: 二項演算子 '<<' : 型 'std::string' の右オペランドを扱う演算子が見つかりません (または変換できません)。 です。意味がわかりません・・・
多分 #include <string>
>>878 あ、コンパイルはできました。ありがとうございます。
・・・でもincludeしてなかったのに
private
string theName;
でコンパイルエラーでなかったんですが。
多分stringの定義とoperator<<の宣言は別ヘッダになってて <iostream>ではstringの定義部分だけインクルードされてたのだろう。
アドバイスありがとうございます。 何か複雑みたいなのでstring使うときはincludeすることにします。
>>867 実用ならboost::mpl::identity使えよ。
やっていることは全く同じだから。
>>880 宣言があっただけだろ。
>>881 まぁ、std::stringを使うなら<string>をインクルードしておけってこった。
>>882 やってることが全く同じだったら、boostを使う必要は無いのでは?
>>883 宣言だけだと theName = name やEntryのメンバtheNameでエラーになると思うよ。
>>864 5G だと int length がオーバーフローしてないだろうか?
887 :
デフォルトの名無しさん :2006/08/20(日) 10:10:40
Cの関数なら日本語で見つかるんですが c++の関数やiostream、STLを詳しく書いてあるサイトはありますか? ないなら英語でいいので教えてください。
MSDN: ms-help://MS.MSDNQTR.2004JAN.1041/vcstdlib/html/vcoriStandardCLibraryReference.htm
892 :
891 :2006/08/21(月) 13:04:08
894 :
デフォルトの名無しさん :2006/08/21(月) 20:55:31
内部で確保したバッファを任意の型で取り出すクラス class buf{ char* buf_;//ここにバッファが確保されているとする template <typename T> T operator [](size_t idx); }; を定義して、[]演算子でアクセスしようと思ったんですが、どう書けばいいのかわかりません template <typename T> T get(size_t idx); など関数を定義すれば buf b; int val; val = b.get<int>(0x0012);//バッファ内の0x0012をintとして取り出す 可能なんですが・・・ val = b[0x0012]<int>;//こんなかんじ???
val = b.operator[]<int>(0x0012) ; 本当にこんなことがやりたいかどうかは知らん。
>>895 私もその呼び出し形式は考えたんですが、
そこまでやるならget()等通常のメンバ関数呼び出しにしようかなと・・
>>896 ありがとうございます
読んでみます
配列を動的に確保したとします int *a; a=(int *)malloc(5*sizeof(int)); こうするとa[0]からa[4]まで使えますが、 後から配列の要素数を減らして不要な配列を解法したいときはどうすればいいんでしょうか? free((a+2)); とかやるとa[0]とa[1]だけ使えてa[2]から先は開放されるんでしょうか?
>>898 realloc
C++ならstd::vector使った方が楽。
この場合は swap使え が正しい答えじゃね?
903 :
901 :2006/08/21(月) 22:58:54
>>902 あーいや
>後から配列の要素数を減らして不要な配列を解法したい
こう書いてあったからさ
あ、resizeすればいいのか
困った。こういう場合にBの宣言とtypedefで衝突して、 AがBを後方参照できないんだけど、回避策あるかなあ? class B; class A{ public: void f(B& b){} }; template<class T> class BBase{ public: }; typedef BBase<int> B; int main(){ Bb; }
大抵のvectorの実装では、要素の数を減らしても、 内部で確保されているメモリは減らないけどね。
>>905 たぶん、そういうレスのために
>>901 を用意していたのだろう。
↓「でも、OSにメモリが・・・」
>904 前方宣言は正しく
>> 908 ?
>>904 Aの前でBをtypedefするか
A::fをメンバ関数テンプレートにするか
くらいかなぁ?
template<class T> class BBase; typedef BBase<int> B; class A{ public: void f(B& b){} }; template<class T> class BBase{ public: };
んーー、普通に先行宣言するなら template<class T> class BBase; typedef BBase<int> B; class A { ... }; だけど、そういうこと言ってるんじゃなくて、 class Bというのが別にあって、 それがtypedefした名前とぶつかってるって話だよね。 例えば、struct statなんてのは、関数のstat()と名前がかぶっているんだけど 直前に"struct"を付ける事で回避できる(同じスコープで同時に使用できる)から class Bに限っては、直前に"class"をつければ使えるかもしれないね。 試してないけど。
>>912 すんません、絡まってたんでわかりずらかったんですが、
911,912さんので解決です。どうもです。
typedef class... B; を class B; で前方宣言したつもりだったのか。 そりゃうまくいかない。
memcpy(_iconGroupData + offset, &grpEntry, sizeof(GRPICONDIRENTRY)); このソースの+とはどういう意味なのでしょうか?
>>915 おそらく&_iconGroupData[offset]と同じこと。
>>898 通常、サイズ変更は大きなコストを支払うことになるから、
あらかじめ適切なサイズを確保することにしたり、
一時領域を使い廻したりすることを考えた方がよいことがある。
C++ ってメソッドをクラス定義の外に書く事って出来ないの? メソッドを全く持たない class foo があったとして、 foo を弄らずに foo::bar() を後から定義して myfoo.bar() みたいな感じで呼び出すみたいな。
継承すれば?
>>920 クラス定義内で宣言した奴を外で定義できる。
クラス定義外でメンバの宣言を追加すことは出来ない。
宣言と定義は違う
>>922 クラス定義内で宣言していないメソッドを追加する事が出来ないかなと考えていました。
特に必要なわけではないのですが、文法上問題無さそうなのに何でだろうと思いまして。
>>924 勝手にメンバ関数追加できたら private も糞もねーな。
文法上の問題がなかったとしても概念上は問題ありまくりだ。
>>920 ヤマシタ! ヤマシタ! オマエズルイモン!
>>925 private は考えてませんでした。
後から定義したメソッドからはアクセス不可にするのでも良いような気がしますが、
言語仕様としては複雑になってしまいますね。
アウターワールドは開始直後のワカメみたいなのに殺されて以来プレイしていません。
ヤマシタだけでわかるなんて相当好きなんじゃん
>>924 そもそもC++をなんでもありと思うのが間違い。
C++(に限らないことのはずだが)どんな機能もそれにはきちんとした必要性があったから導入された。
あ、でももしoperator .の多重定義ができるようになったとしたら、
外見上924の考えているのと同じことになりそうだけど。
なりません
とりえあず
>>920 はgeneric function風の
bar(myfoo)の多重定義で我慢して。
>>920 template< typename Function, class T > class dynamic_method {
Function fun; T * obj;
public:
typedef typename function_traits
< typename remove_pointer<Function>::type >::result_type result_type;
dynamic_method( Function fun, T * obj ) : fun( fun ), obj( obj ) {}
result_type operator()() const {
return fun( *obj );
}
template< typename A1 > result_type operator()( A1 & a1 ) const {
return fun( *obj, a1 );
}
};
template< typename T > struct use_dynamic_method {
template< typename Function >
dynamic_method< Function, T > operator->*( Function func ) {
return dynamic_method< Function, T >( func, static_cast<T*>(this) );
}
};
class foo : public use_dynamic_method<foo> {};
void bar( foo & obj, char const * message ) { cout << message << endl; }
int main() {
foo myfoo;
(myfoo->*bar)("dynamic call");
}
変態とか言うな
変態にもほどがある。
dynamicと言ってる割にはstaticなのね。
>>934 あ…
さ、最初は連想配列に、function オブジェクト突っ込んでほんとに動的に追加できるように
しようと思ってたけど、可変引数に対応させようと色気だしてごちゃごちゃやっているうちに
静的になってしまったんだよ。ホントだよ。
呼び出し方は、↓のように文字列か、数字をキーにしようと思ってた。
(myfoo->*"bar") = function< void ( foo & ) >( bar ); // 関数追加
(myfoo->*"bar")();
(myfoo->*"dar")(); // throw そんな関数は存在しない例外
見たいな。
ちなみに、仮想関数的な振る舞いは最初から考慮しておりません。
元ネタ見たい人はboostスレに行ってねw
こんなのはどうよ。932でoperator ->*をメンバにする意図がわからなかった。その後935が書かれた。 template<typename T, typename Functor> boost::function<void ()> operator ->*(T obj, Functor f) { return boost::bind(f, obj); } class Hoge {}; void hello(Hoge) {std::cout << "Hello" << std::endl;} int main() { Hoge hoge; (hoge->*hello)(); }
>>937 それだと、複数引数に対応できないから、無理に operator->* 使うより
普通に hello( hoge ); で呼んだほうがええね。
>>932 よくわからないけど凄い。
ちなみに
template< typename Function >
dynamic_method< Function, T > operator->*( Function func ) {
のtemplate引数Functionは明示的にinstantiateされていないけど、
コンパイラが自動的に推測してくれるのでしょうか?
(myfoo->*bar)("dynamic call");
で利用されているからFunction = void (foo&, char const *)とか
>>940 >>932 じゃないけど解説してみる。
use_dynamic_methodをCRTPでpublic継承すると、operator ->* () が使えるようになる。
operator ->* ()は、関数オブジェクトを引数にとり、dynamic_method型のオブジェクトを返す。
ここでいう関数オブジェクトとは、use_dynamicmethodを継承するクラスへの参照と、任意の型を引数に取るもののこと。
ここでは、任意の型はひとつしか引数の取れないが、
dynamic_methodをちょっといじれば、現実的に問題のないくらい多数の引数を取るようにもできる。
dynamic_methodは、関数オブジェクトのラッパ。
使用例を分かりやすく書くと
myfoo.operator->*(bar) ("dynamic call") ;
operator->*を呼び出すことで、dynamic_method型のオブジェクトが返される。
で、そのoperator()()が呼び出されることで、実際の本当に呼び出したい関数オブジェクト、barが呼び出される。
でもまあ、bar(myfoo) ; でいいじゃんというのはまた別の話
942 :
941 :2006/08/24(木) 01:02:03
ごめん、関数オブジェクトじゃなくて、関数ポインタだった。
動的じゃないと言われてカッとなってやった。今は深く反省している。 template< typename T > struct dynacall { T & o; any & c; dynacall( T * object, any & content ) : o( *object ), c( content ) {} template< typename R > R operator()( type<R> ) { return (any_cast< function< R ( T & ) > >(c))(o); } template< typename R, typename A1 > R operator()( type<R>, A1 a1 ) { return (any_cast< function< R ( T &, A1 ) > >(c))(o,a1); } template< typename R > R value_of() const { return any_cast< R >(c); } }; template< typename T > struct prototype { typedef map< string, any > map_type; map_type m; dynacall<T> operator->*( typename map_type::size_type index ) { typename map_type::iterator it = m.begin(); advance( it, index ); return dynacall<T>( static_cast<T*>(this), it->second ); } dynacall<T> operator->*( typename map_type::key_type const & key ) { return dynacall<T>( static_cast<T*>(this), m[key] ); } template< typename F > void register_fun( typename map_type::key_type const & key, F f ) { m[key] = function< remove_pointer<F>::type >(f); } template< typename V > void register_val( typename map_type::key_type const & key, V v ) { m[key] = v; } };
944 :
943 :2006/08/24(木) 16:55:13
>>943 の使い方
class foo : public prototype<foo> {};
int bar( foo & x, int a ) { return a; }
int main() {
foo myfoo;
myfoo.register_fun( "bar", bar );
myfoo.register_val( "hage", 12 );
cout << (myfoo->*"bar")( type<int>(), 10 ) << endl; // 10 と表示
cout << (myfoo->*0)( type<int>(), 20 ) << endl; // 20 と表示
cout << (myfoo->*1).value_of<int>() << endl; // 12 と表示
}
どうみても変態です。
必要なヘッダは、<boost/any.hpp> や、<boost/function.hpp> など。
良い子でなくてもマネしちゃだめ。
anyは正直反則だと思う。 でも、C++0xの標準ライブラリに入ることが予定されているんだよな……。
病気になるよ
だれか>939にお答えを…!
>>947 関数f の引数として、関数ポインタを渡す場合、f( bar ) と記述してもいいことになってます。
なので、(myfoo->*bar) は、(myfoo->*&bar) と同じ意味になります。
よって、Function の型は、「 void (*)( foo &, char const * ) 」 つまり関数ポインタ型。
このままだと、function_traits に渡せないので、remove_pointer して、「 void ( foo &, char const * ) 」にしているわけです。
949 :
943 :2006/08/24(木) 19:42:30
>>943 何も考えずに、prototype ってクラス名にしたけど、
冷静になると、ぜんぜん prototype ってカンジじゃねーな。
map_type m; を、static map_type m; にすれば、少しは prototype っぽくなるかも。
>>948 どうもありがとうございます。普通のtemplate classの場合と違って、
myfoo->*<void (*)(foo&, char const *)>bar
と書かなくて良いのは、何か特例なんでしょうか?
>>950 関数テンプレートのテンプレート引数は引数の型から推論される。
std::max(4, 2);などと書けるのと同じ。
オtットット夏だぜ
C++初心者ですが、 class Camera; などのような使用クラスの宣言とはどんなものなのでしょうか? ヘッダファイルに書いてあったのですが。 入門書などではClass Camera{---}; Camera camera1;などのように宣言 してありチンプンカンプンです。
>>953 Cameraがクラスであることを宣言するが、どんなクラスであるかの定義は行わない。
955 :
953 :2006/08/25(金) 00:12:37
intとかunsigned intとかの最大値をtemplateで取得することって できましたっけ? template<class T> T GetMaxSize(T t){} 的な感じで。
#include<limits> template<typename T> T GetMaxSize(const T&){ return std::numeric_limits<T>::max(); }
うぅ、知りませんでした。ありがとうございます。 return (T)(-1); 的な感じでできるかなと思ってましたが、unsignedとsignedの見分けが・・ とか思ってました。numeric_limitsは特殊化で全型分用意してるみたいですね。 最近自分のコードの型あふれに対する対処がすごく甘いなあと。 なんというか包括的な対処法っていうのはなんかないんですかねえ。(例外飛ばすとか) みなさんどうしてますか?
C++を使うな。終り。
>>みなさんどうしてますか? お前だけだよ
>>959 boost::numeric_cast
これはひどい
ばかばっか
>>959 ありがとうございます。たぶん解決しそうです。
>>965 今のところunsignedでも動いてます
まちがえ
>>962 ありがとうございます。たぶん解決しそうです。
>>965 今のところunsignedでも動いてます
unsignedに対してシフト演算(やそれに類するかけ算)をしたときに、 いちいち例外投げられたら面倒でやりきれないからじゃないの? と勝手に想像してみる。
ゼロ除算で例外が飛ぶことを考えればオーバーフローも例外扱いされるべきだとは思う。(シフト演算の場合は除く)
しかし、そうするとあらゆる演算に numeric_cast<int>(i * 3) とかしなくちゃいけなくなるな
>>970 int * 3 の評価の時点でオーバーフローする場合、
オーバーフローの結果である int 型の値に対して
numeric_cast<int> しても意味無い。
ほんと、boost馬鹿って迷惑だよな
そうか?
ん?その評価をするためにcastが必要なんだろ? int i2 = numeric_cast<int>(i * 3); iの3倍をi2に入れるときにbad_numeric_castを出させるには こうするしかないでしょ。
>>974 i の型は何だ? int 以下のサイズの整数型なら、その numeric_cast は利かないだろう。
>>974 boostばかり使っていると、こういう馬鹿になりますよ。
>>974 演算のオーバーフローについてチェックしてくれてるわけじゃないから
袋叩きw
>>974 それは次のコードと等しい。
int temp = i * 3;
int i2 = numeric_cast<int>(temp);
お前が望んでいる動作は、仮にsizeof (int) < sizeof (long)だとすれば、一例だが次のような感じになる。
int i2 = numeric_cast<int>(implicit_cast<long>(i) * 3);
それとも、もしやiはint型ではないと言うつもりか?
それ位で許してやれよw
あれ?じゃこういう演算のオーバーフローってどうすんの? int i; i = ???; int i2 = i * 3; 毎回if(i < INT_MAX/3)みたいに事前にあふれチェック?
何言ってんだ、こいつ。
>>982 なんか難しいこと言ったか?例えばC#はchecked blockとかで演算の
オーバーフローをチェックできるだろ?
何言ってんだ、こいつ。
次スレ準備中。リンク貼れるようにレス番節約お願い。
読んだ結果だろ。boost::numeric_castは型から型のキャストに ついてチェックしてくれるだけで、演算についてはしてくれないだろ? じゃあ、演算についてはどうするんだ?C#はcheckedとかあるよな? で、C++ってどうすりゃいいんだったっけ?と言っただけだがまだ難しいか?
>>981 なぜ「あれ?じゃ・・・」なのか意味不明だが、ケースバイケースだな。
>>988 まさか本当に「難しいから回答が得られない」と思ってるわけではないだろうな。
お前ら、くだらんたわごとは止めて、新レスのリンクが貼られるまで発言すんな。
>>991 > 新レスのリンク
v(^・^)v プギャーー
シフト演算のつもりで割り算してて、かつ、右辺が0だっていうんなら、 むしろ例外を投げてくれた方がありがたいよ。
>>995 何が「で?」だよw
答え知りたいなら、それなりの質問態度でなw
boost馬鹿って、ほんとに迷惑ですね。
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。