C++相談室 part48

このエントリーをはてなブックマークに追加
1v(^・^)v
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE(VC++など)などの使い方の質問はその開発環境のスレに
お願いします。

  → テンプレその他 >>1-15 付近参照 ←

前スレ
C++相談室 part47
http://pc8.2ch.net/test/read.cgi/tech/1139931895/l50
2v(^・^)v:2006/03/15(水) 20:54:04
3v(^・^)v:2006/03/15(水) 20:54:48
4デフォルトの名無しさん:2006/03/15(水) 20:56:15
5v(^・^)v:2006/03/15(水) 20:56:48
■基本■
[C++ FAQ]
 http://www.parashift.com/c++-faq-lite/
 http://www.bohyoh.com/CandCPP/FAQ/ (日本語)
  Cとその仕様を比較しながらの解説なので分かりやすい。
  ***** 質問の前に必ずこの二つに目を通してください *****

[禿 Stroustrup]
 http://public.research.att.com/~bs/
[C++ International Standard]
 http://www.kuzbass.ru/docs/isocpp/
 http://www.kuzbass.ru/docs/ansi_iso_iec_14882_1998.pdf
 http://www.iso.org/iso/en/CatalogueDetailPage.CatalogueDetail?CSNUMBER=38110&ICS1=35&ICS2=60&ICS3=
[JTC1/SC22/WG21 - C++]
 http://www.open-std.org/jtc1/sc22/wg21/

[C/C++ Users Journal]
 http://www.cuj.com/
[cppll (ML)]
 http://www.trickpalace.net/cppll/ (日本語)
6v(^・^)v:2006/03/15(水) 21:00:04
7v(^・^)v:2006/03/15(水) 21:04:57
8デフォルトの名無しさん:2006/03/15(水) 21:05:38
9デフォルトの名無しさん:2006/03/15(水) 21:09:55
■関連スレ■
【初心者歓迎】C/C++室 Ver.25【環境依存OK】
 http://pc8.2ch.net/test/read.cgi/tech/1140963340/l50
【C++】STL(Standard Template Library)相談室 4
 http://pc8.2ch.net/test/read.cgi/tech/1130680264/
C/C++の宿題を片付けます 62代目
 http://pc8.2ch.net/test/read.cgi/tech/1141363718/
C/C++でのWindowsPrograming議論スレ(質問お断り)
 http://pc8.2ch.net/test/read.cgi/tech/1049790146/
managed C++ やろうぜ!! 002
 http://pc8.2ch.net/test/read.cgi/tech/1139043535/
C++/CLI について語ろうぜ  Part2
 http://pc8.2ch.net/test/read.cgi/tech/1142147319/l50
くだすれC++/CLI(初心者用)
 http://pc8.2ch.net/test/read.cgi/tech/1142144110/l50
ATL/WTL Part4
 http://pc8.2ch.net/test/read.cgi/tech/1134388951/
【雑談】C/C++【その1】
 http://pc8.2ch.net/test/read.cgi/tech/1098817686/l50
10デフォルトの名無しさん:2006/03/15(水) 21:10:26
STLつかうと一気に実行ファイルサイズが10倍に?!
11デフォルトの名無しさん:2006/03/15(水) 21:59:56
>10
環境によるだろ。
俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力
ランタイムを使用するようにして使っているが、例えばstd::vectorを
使っても使わない時と比べ10Kほどしか増えない。
12デフォルトの名無しさん:2006/03/15(水) 22:02:36
具体例くらい挙げれば?>>10
13デフォルトの名無しさん:2006/03/15(水) 23:10:25
>>11
すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。
14デフォルトの名無しさん:2006/03/15(水) 23:11:08
C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
とかいうエラーが出るんだけどこれってどうすればいいの?

#include <stdafx.h>

後氏ね。

言葉が悪いな。それで教えているつもりか。
まぁヒントぐらいにはなったな。
うむごくろう。
15デフォルトの名無しさん:2006/03/16(木) 00:18:06
プロジェクトのプロパティで、"プリコンパイル済みヘッダーを作成する"にする
というかVSすれに行ってくらはい。
16デフォルトの名無しさん:2006/03/16(木) 01:40:12
>>12,>>15
新参者を発見しますた。(・∀・)ニヤニヤ
そういやもう春休みの時期かぁ。
17デフォルトの名無しさん:2006/03/16(木) 07:24:29
なんで変なところまでテンプレになるの?
某厨房板の地鎮祭みたいなものか?
18デフォルトの名無しさん:2006/03/16(木) 11:22:38
新参者を見つけてニヨニヨするスレはここですか?
19デフォルトの名無しさん:2006/03/16(木) 11:40:19
なんでただでさえ長いテンプレに変なもんつけるんだか。
20デフォルトの名無しさん:2006/03/16(木) 12:41:45
あっちこっちから参照されるサブ関数はC++の場合どうするのが
いいんでしょうか?
サブ関数をまとめたクラスを作って使用もとでフレンド宣言とかでしょうか?
アドバイスよろしく
21デフォルトの名無しさん:2006/03/16(木) 12:50:47
>>20
サブ関数とやらは全部適当なnamespaceに放り込んどけ。
22デフォルトの名無しさん:2006/03/16(木) 12:53:58
>>20 なんでフレンド?
てけとーなクラス作って、
public static な関数にしてしまえばいいんじゃない?
まぁ >>21 みたく namespace でもいいけどさ。
23デフォルトの名無しさん:2006/03/16(木) 14:42:17
namespace mylib {
 namespace math {
 // 数学関係の関数
 }
 namespace graphics {
  // 画像関係の関数
  namespace io {
   // 画像関係の入出力
  }
 }
 namespace utility {
 }
 ....
}
のようにしてる。適当なnamespaceの中に、用途別のnamespaceがある感じ
2420:2006/03/16(木) 17:09:21
ありがとぅん
家に帰たら挑戦してみます。
25デフォルトの名無しさん:2006/03/16(木) 18:38:10
>>22
Javaじゃないんだからw
26デフォルトの名無しさん:2006/03/17(金) 21:33:22
>>前スレ998
http://pc8.2ch.net/test/read.cgi/tech/1139931895/998

で、ある特定のライブラリ「boost」がその実装を想定していなかったとして
ケツを持ち込む相手は?

# あんた、K さんだろ?
27デフォルトの名無しさん:2006/03/17(金) 21:38:21
なんでケツが関係あるの?さっぱりわかんね。
亜ふぉで素か?
28デフォルトの名無しさん:2006/03/17(金) 22:06:54
おろっ? K じゃなかったか・・・ これは失礼

# はー、つまんね
29デフォルトの名無しさん:2006/03/17(金) 22:34:39
>>28
いや、俺だって。俺、俺!
30デフォルトの名無しさん:2006/03/17(金) 23:01:11
俺は?
31デフォルトの名無しさん:2006/03/17(金) 23:11:32
俺も?
32デフォルトの名無しさん:2006/03/18(土) 06:50:08
あれかい?
デリートしたオブジェクトポインタは直後にNULLにしといた方が初心者には何かと安心かい?
33デフォルトの名無しさん:2006/03/18(土) 06:52:02
うん
34デフォルトの名無しさん:2006/03/18(土) 06:55:43
二重 delete が起きるコードなんてたいていバグってんだから、
バグ発覚の可能性を除去するなんて勿体無いとおもう。
35デフォルトの名無しさん:2006/03/18(土) 07:34:06
もしコピーコンストラクタが代入に対処できていたら、大変な事になってましたね。
左辺が、意図したデータを持ってる時の代入か、はたまた初期化の時の単なるゴミデータか判別できませんもんね。
ゴミの時にメソッドなんか呼ぼうもんなら終了ですもんね。

以上、今日の日記。
36デフォルトの名無しさん:2006/03/18(土) 11:02:56
初めてconstの有用性を知ったとき、関数の引数をconst参照で渡す効能を知ったとき、
あるいは前置++, --演算子の後置に対する効率上の違いを知ったとき等、
人は十字軍になるものなんだろう。Effective C++にも書いてあるけれど。

何事も行き過ぎはよくないという一例だな。
37デフォルトの名無しさん:2006/03/18(土) 16:18:16
>>34
>たいていバグ
じゃなくて、明らかなバグ
でも、delete 後 NUL代入する「信仰」は後を絶たない
何故だろう??
即落した方が、遥かに有用だと思うのだが
38デフォルトの名無しさん:2006/03/18(土) 16:26:34
すぐエラーで落ちるとは限らない
39デフォルトの名無しさん:2006/03/18(土) 17:05:06
>>37
delete 自体は問題なくてもデストラクタが複数回呼ばれちゃいかんだろ?
で、デストラクタがあるオブジェクトかどうかでNULLは代入したりしなかったりするのはナンセンスだろ?
40デフォルトの名無しさん:2006/03/18(土) 17:46:15
>>37
たとえば、T型へのポインタの配列へのポインタT** ptrをメンバに持ち、要素をクリアするメソッドを定義すると

void clear() {
 if (ptr) {
  for (int i = 0; i < size(); ++i) delete ptr[i];
  delete[] ptr;
  ptr = 0;
 }
}

このclear()は、もしptrに0を代入していなければ、二度呼び出された時点で不正になる。

要素が存在する場合に限ってclear()を呼び出せるような仕様にするより、
いかなる場合でもclear()は要素をクリアするような仕様の方が、見通しがいいと思う。

if (!my_container.empty()) my_container.clear(); // 要素が空かのチェックつき。こう書くより
my_container.clear(); // こう書けば、要素のあるなしに限らずクリアしてくれる方が、私は嬉しい

ただし、最初のdeleteループでは、各要素に0を代入したりはしない。
すぐ次のdeleteで、各要素にアクセスできなくなるからね。
41デフォルトの名無しさん:2006/03/18(土) 17:51:57
>>40
void clear() {
if (empty()) return;
42デフォルトの名無しさん:2006/03/18(土) 17:59:42
オブジェクトの初期化を ob = 1 ってできないようにすれば
代入時にはコピーコンストラクタが呼び出せないのは
簡単にわかるのにっておもいました。

以上C++学習中の今日の日記
43http://www.vector.co.jp/soft/win95/util/se072729.html:2006/03/18(土) 18:16:58
名ソフト TextSS の64bit化ってできない?
44デフォルトの名無しさん:2006/03/18(土) 18:22:21
仕様的にdeleteのNULLチェックは入らないって話をどこかで見た覚えがある。
if(!foo) delete foo;

delete foo;
で良いって話。
つまり重複開放も問題ない気がする。
45デフォルトの名無しさん:2006/03/18(土) 18:26:36
46デフォルトの名無しさん:2006/03/18(土) 18:27:53
ちがうー。deleteにヌルを渡しても無視してくれるだけだ。
恐ろしい勘違いをしているぞ。
47デフォルトの名無しさん:2006/03/18(土) 18:30:29
>>45
ちとMSを尊敬
48デフォルトの名無しさん:2006/03/18(土) 18:44:13
>>37
MS のせいだな。 >>45 とか SAFE_〜() とか。

みんな auto_ptr() 使えばこんな議論も要らないのに。
スコープから外れる直前のポインタを delete したときはヌル埋めは不要。
スコープに残ってるポインタを delete したときはヌル埋めは有効。
auto_ptr() がうまく働いてくれる。
49デフォルトの名無しさん:2006/03/18(土) 19:01:06
パフォーマンスを気にしたいところでは auto_ptr 使いたくなかったりするんだお
50デフォルトの名無しさん:2006/03/18(土) 19:04:47
そういや昔同じはなしになったときに、生ポインタと比べてどれだけ遅いのか計ってた香具師がいたな
結果はきれいさっぱり忘れてしまったが
51デフォルトの名無しさん:2006/03/18(土) 19:11:44
>>49-50
全部インラインで実装できるからパフォーマンスに影響は無いはずなんだけど。
実測して言ってるの? >49
52デフォルトの名無しさん:2006/03/18(土) 19:13:04
インライン化はされるとは限らないんだお
53デフォルトの名無しさん:2006/03/18(土) 19:17:12
インライン化はされないとは限らないんだお
54デフォルトの名無しさん:2006/03/18(土) 19:20:13
>>53
だから遅くなるかもしれないことは避けるんだお
55デフォルトの名無しさん:2006/03/18(土) 19:24:07
>>51
インラインで実装「できる」ことと
インラインで実装「しなければならない」ことは
ちゃんと区別しないと、どこへ行っても文盲扱いされるぞ
56デフォルトの名無しさん:2006/03/18(土) 19:34:31
>>54
そんなこと言ってたら標準のテンプレートも boost もほぼ全滅だな。正気か?
57デフォルトの名無しさん:2006/03/18(土) 19:40:56
「パフォーマンスを気にしたいところで」と言ってるんだお
そういうところでは boost なんてもってのほかだお
5851:2006/03/18(土) 19:45:50
>>55
あぁ「インラインで実装」じゃ意味がわからないな。
「全部インライン展開できるはずだから〜」に言い換えておこう。
59デフォルトの名無しさん:2006/03/18(土) 19:47:00
>>57
速度は実測が基本。
原因が明らかになる前にコードを劣化させるなんてもってのほか。
60デフォルトの名無しさん:2006/03/18(土) 19:47:19
まあ、deleteの話に戻るが、例外処理で判定すんのが面倒だからNULL代入してるだけ。
一律 delete 並べれば良いだけだから。
61デフォルトの名無しさん:2006/03/18(土) 19:50:59
>>60
それも auto_ptr のほうがいいだろ。
62デフォルトの名無しさん:2006/03/18(土) 19:51:46
やっぱり実測しろって展開になったw
誰かやれよ
63デフォルトの名無しさん:2006/03/18(土) 20:06:32
>>39
> delete 自体は問題なくてもデストラクタが複数回呼ばれちゃいかんだろ?
一つのインスタンスに対してデストラクタが
複数回呼ばれるロジック自体がおかしい、直すべきだと思う

>>40
>>41の通り、あんまし理由になっていない希ガス

>>60
> まあ、deleteの話に戻るが、例外処理で判定すんのが面倒だからNULL代入してるだけ。
ごめん、意味判らない
64デフォルトの名無しさん:2006/03/18(土) 20:58:11
自分でdelete呼んだら
もうそのコードは間違っているという認識だけどな
Boostでdeleteを検索すると
ptr_containerさえ一個もなかったりする
65デフォルトの名無しさん:2006/03/18(土) 21:06:40
直接 I/O したら
もうそのコードは間違っているという
のと同じ論法だな
66デフォルトの名無しさん:2006/03/18(土) 21:09:46
>>65
むしろそっちのほうがまだ納得できる理屈なんだが
67デフォルトの名無しさん:2006/03/18(土) 21:41:21
>>66
せいぜい、間違ったコードでレスしてくれたまえ
68デフォルトの名無しさん:2006/03/18(土) 22:15:58
コンストラクタ・デストラクタにくくって話をしてる奴と、話をしてない奴がいる。
TextSS のWindowsXP(Professional)64bit対応化おながいします

もしくは64bitにネイティブ対応したテキスト置換ソフトありますか?

そういや64bitにネイティブ対応している2chブラウザてありましたっけ?


70デフォルトの名無しさん:2006/03/18(土) 23:49:02
auto_ptrのパフォーマンスを気にするのなら、そもそもc++を選択しているのが
間違っているような気が……

まあ、パフォーマンス気になる部分をクラスに切り出して、その中でチューニング
するのが程良い妥協案じゃない?
71デフォルトの名無しさん:2006/03/18(土) 23:50:45
boost::scoped_ptrは?
それすら嫌なら自分で作れば?
72デフォルトの名無しさん:2006/03/18(土) 23:52:28
質問です。
数値を取るようなテンプレートを用いたクラスを作成し、継承して利用します。
たまたま2箇所で同じ数値を渡して特殊化した場合、staticメンバが
共有されるのはしょうがないことですか?

文章だけだとわかりにくいので例で。
サイズをTで渡すと、継承したクラスのインスタンス数をカウントし、
そのメモリ容量を返す以下のクラスを考えます。

template <int T> class Count{
public:
  static int num;
  Count(){num++;}
  ~Count(){num--;}
  
  static int getmem(){ return num * T;}
};

template <int T> int Count<T>::num = 0;


73デフォルトの名無しさん:2006/03/18(土) 23:52:45
ここで、以下のようにクラスA,B,Cを作ります。
A,Bはサイズが同じ。

class A : public Count<8>{
  int i,j;
};

class B : public Count<8>{
  long long l;
};

class C : public Count<16>{
  long long l,m;
};

int main(int argc,char** argv){
  A a1,a2,a3;
  B b1,b2;
  C c1,c2,c3,c4;
  
  printf("A = %d\n",A::getmem()); //8*3=24を期待
  printf("B = %d\n",B::getmem()); //8*2=16を期待
  printf("C = %d\n",C::getmem());
}

74デフォルトの名無しさん:2006/03/18(土) 23:52:51

Aは3つ、Bは2つインスタンスがあるので、printfした時は24,16が
表示されて欲しいのに、ともに40が表示されてしまいます。

このような現象を防ぐ方法はありませんか?

(Countが<int T>をとるのではなく、<class T>として<A>や<B>、<C>で特殊化し、
 getmemではnum*sizeof(T)なら対応できるのはわかるのですが、
 今回はこのCountに相当する部分がライブラリで変更できない)
75デフォルトの名無しさん:2006/03/19(日) 00:01:57
void foo1(){
...
++bar;
...
}
void foo2(int hoge){
...
bar*=hoge;
...
}
上記のように、一部分だけ違う関数が必要なんです。
引数が変わり、また非常に多く呼び出される関数なのですが、
重複したコードを書かないようにする、コストの低い良い方法ってないでしょうか?
76デフォルトの名無しさん:2006/03/19(日) 00:03:02
>>72-74
Count が変更できないなら無理。
そのライブラリの設計ミスか、そのライブラリが
想定していない使い方をしてるんだろう。
77デフォルトの名無しさん:2006/03/19(日) 00:06:44
>>75
void foo_first(int& bar);
void foo_last(int& bar);
void foo1() { int bar; foo_first(bar); ++bar; foo_last(bar); }
void foo2() { int bar; foo_first(bar); bar*=hoge; foo_last(bar); }

first をコンストラクタ、 last を
7877:2006/03/19(日) 00:08:05
ごめんしくじった。

first をコンストラクタ、 last をデストラクタとし、
int bar をメンバとするクラスを作るといいかも。
79デフォルトの名無しさん:2006/03/19(日) 00:14:11
その、一部分だけ違うところを、関数オブジェクトをとるようにするとか。
80デフォルトの名無しさん:2006/03/19(日) 00:30:04
>>77
ネストの深い所にあって、前後を分割できないんです・・・

>>79
引数の数や型が違う場合に上手く出来たでしょうか?
ちょっとやってみます。
81デフォルトの名無しさん:2006/03/19(日) 00:37:48
>>80
boost::bindなんかを使って引数の数などを揃える。
82デフォルトの名無しさん:2006/03/19(日) 01:27:58
>>70
> auto_ptrのパフォーマンスを気にするのなら、そもそもc++を選択しているのが
> 間違っているような気が……

その理論だと、すべて「アセンブラでかけ」という結論になっちゃうよ。
極論房はこれだからダメなんだよ。

ソフト開発に極論はありませんがな。
83デフォルトの名無しさん:2006/03/19(日) 01:41:18
auto_ptr のパフォーマンスを疑うようなやつはコンパイラ実装者を馬鹿にしすぎ。
84デフォルトの名無しさん:2006/03/19(日) 01:45:06
>>82
auto_ptrのパフォーマンスを論じてんのが極論なんだろ。
85デフォルトの名無しさん:2006/03/19(日) 01:54:24
>>81
ライブラリが必要なんですね。

とりあえずコピペで行きます。。
86デフォルトの名無しさん:2006/03/19(日) 01:56:49
だから適当なコード書いて実測しろと
話はそれからだ
87デフォルトの名無しさん:2006/03/19(日) 02:00:38
実測値とか依存になりえるもの全てに依存した数値だから困る
てかパフォーマンス以外にもautoptr使いたく無い場面ってあるある
88デフォルトの名無しさん:2006/03/19(日) 02:01:54
日本語が酷い事になってるが突っ込みは無しで
89デフォルトの名無しさん:2006/03/19(日) 02:04:48
使えない(vectorの要素とか)場合なら分かるけど
使いたくないって・・どんなんやねん?
90デフォルトの名無しさん:2006/03/19(日) 02:06:31
>>87
そんな微妙な最適化などすべきじゃないだろう。

ソースコードを最適化して、
アセンブラレベルで見たら、加算命令がひとつ消えていました。
最適化は成功したようです。

これは違うだろ?

9170:2006/03/19(日) 02:10:38
>82
直後の2行は無視ですか。そうですか。

auto_ptrて、標準C++ライブラリでもかなりオーバーヘッドの少ないクラスだよね?
そのオーバーヘッドが気になるなんて、どういうデータ構造にしているんだろう?
プログラムの大半がポインタアクセスになるようなプログラムでもないかぎり、
そんなにひどいことにはならんと思うけど……
#流体シミュレーションとか有限要素解析とか、そっち系かな?
92デフォルトの名無しさん:2006/03/19(日) 02:15:15
93デフォルトの名無しさん:2006/03/19(日) 02:16:09
>>89
まぁ確かにautoptrの挙動で困る場面ならautoptr使えないようになってるけどな。
94デフォルトの名無しさん:2006/03/19(日) 02:19:16
使わなくて済むんなら使わなくていいんじゃないか?
C++にはいろいろな選択肢がある、というだけだし
95デフォルトの名無しさん:2006/03/19(日) 02:20:57
>>91
標準C++ライブラリと比較してオーバーヘッドを語られてもなぁ。
そんな話は意味ないだろ。
96デフォルトの名無しさん:2006/03/19(日) 02:32:22
>#流体シミュレーションとか有限要素解析とか、そっち系かな?
そっち系なら、生ポインタ推奨なのかな
特殊用途だとは思うけど
97デフォルトの名無しさん:2006/03/19(日) 02:33:45
スマートポインタのパフォーマンス気にしないなら、JavaいけJava
98デフォルトの名無しさん:2006/03/19(日) 02:34:34
いやDやろうぜ
業務には使えないが
99デフォルトの名無しさん:2006/03/19(日) 02:36:10
もういいから好きなの使いなよ
10070:2006/03/19(日) 02:46:09
>95
auto_ptrのオーバーヘッドがどの程度か示さずに語られてもなぁ。
そんな話は意味ないだろ。

>96
でしょうね。普通、データ数が物凄いことになるから、データにアクセスするときの
オーバーヘッドがバカにならない……
チューニングの最後の方には変わりないけど、そこまで踏み込まなきゃいけない
ことが多々あるようですね。
101デフォルトの名無しさん:2006/03/19(日) 02:57:25
auto_ptr のどこにオーバーヘッドがあると思ってるんだ?
http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/memory-source.html
102デフォルトの名無しさん:2006/03/19(日) 07:03:49
>>100
auto_ptrなんて、生のポインタを使うのとまったく同じなわけだが。
まさか今日び、テンプレートをサポートしていながら、
インライン展開をサポートしていないコンパイラも珍しい。
103デフォルトの名無しさん:2006/03/19(日) 07:23:32
インライン展開されると不具合が出るコードktkr
10470:2006/03/19(日) 12:36:24
ああ、そりゃそうか。
ポインタ自体のオーバーヘッド(ポインタごしのアクセス / 直接アクセスの違い)と
ごっちゃにしていたよ。

auto_ptrとしてのオーバーヘッドはポインタのコピー(移動)ぐらいか。
105デフォルトの名無しさん:2006/03/19(日) 12:50:54
テンプレートを使うデメリットは、コードサイズの増加?
106デフォルトの名無しさん:2006/03/19(日) 12:57:09
コードサイズの増加は、手書きでも同じようにコーディングしたらあんまり
変わんないんじゃない?

どっちかというと、テンプレートの欠点は
・コンパイル時間の増加
・(externを実装したものが少ないので)ヘッダーに実装詳細まで
 含まれるのでゴチャゴチャする
のような気がする
107デフォルトの名無しさん:2006/03/19(日) 13:23:18
確かにヘッダに実装書くのきもちわるい
108デフォルトの名無しさん:2006/03/19(日) 13:35:16
>>100

鸚鵡返しは、低能の証だと何度言ったらわかるんだ?
10970:2006/03/19(日) 13:50:15
いや、コメント考えるのタルかったんで。何度も言われた記憶ないし。
で、auto_ptrのオーバーヘッドってなに?
110デフォルトの名無しさん:2006/03/19(日) 13:59:38
>>109

馬鹿
111デフォルトの名無しさん:2006/03/19(日) 14:01:23
>>110
禿同。あれをsmart_ptrと名付けなかった連中を誉めたい。
11270:2006/03/19(日) 14:11:56
内容の無いコメントするのも無能の証だとおもうけど?

auto_ptrはauto_ptrでsmartだと思うけどね。
あれのおかげでRAIIとか所有権の明確化/移動がやりやすい。
確かに気を付けないと大怪我するけど、それは「C++だから」ということで。
113デフォルトの名無しさん:2006/03/19(日) 16:37:20
数字コテ化するのは煽りあいが泥沼化してる証だぜ
114デフォルトの名無しさん:2006/03/19(日) 19:09:58
STLのは、auto_ptrでいいと思うけどね。
smartっていうなら、boostのshared_ptr見たいなやつだろう。
こっちは、確かにオーバーヘッドがあるけど、目的が違うしね。
115デフォルトの名無しさん:2006/03/19(日) 19:35:33
もう、70は感情にまかせて書いてるだけか。
116デフォルトの名無しさん:2006/03/19(日) 19:57:53
俺が令状だ
117デフォルトの名無しさん:2006/03/19(日) 20:06:22
話をぶった切ってすみません、質問させてください。
template <template <int> class apply, int n>
struct applier { 
  enum { value = apply<n>::value }; };
template <int n> struct add {
  template <int m> struct result { 
    enum { value = n + m }; }; };
template <int n, int m>
struct applier_add { 
  enum { value = applier<add<n>::result, m >::value }; };
int main() { std::cout << applier_add<2,3>::value << std::endl; }
これが VS.net のコンパイルできて g++ 3.4.4 でコンパイルできないのは何ででしょうか?
また、これを g++ でコンパイルできるようにするにはどうしたらよいでしょうか?

g++で出るコンパイルエラーは↓です
main.cpp:11: error: type/value mismatch at argument 1 in template parameter list
for `template<template<int <anonymous> > class apply, int n> struct applier'
main.cpp:11: error: expected a class template, got ` add<n>::result'
118デフォルトの名無しさん:2006/03/19(日) 20:10:53
>>117
add<n>::template result
119デフォルトの名無しさん:2006/03/19(日) 20:20:15
>これが VS.net のコンパイルできて g++ 3.4.4 でコンパイルできないのは何ででしょうか?
add<n>::resultがテンプレートであることは実体化させてみるまで分からない。
だから、「型でもテンプレートでもないもの」と推定される。
型やテンプレートを期待している場合は、それぞれtypenameとtemplateキーワードが必要。
120119:2006/03/19(日) 20:21:21
VS.netでコンパイルできるのは、単にコンパイラが甘いだけ。
121デフォルトの名無しさん:2006/03/19(日) 20:32:03
>>118
おお!通りました!ありがとうございます。

>>119-120
分かりやすい説明、本当にありがとうございます。助かりました。
122デフォルトの名無しさん:2006/03/19(日) 23:28:49
ACDK (Artefaktur Component Development Kit)っていうライブラリ使ったことある人いませんか?
このACDKのコアライブラリがJavaっぽいクラスライブラリで、(acdk::lang::StringBufferとか)
なかなか使えるんじゃないかとおもってるんですが。
123デフォルトの名無しさん:2006/03/20(月) 09:34:29
久しぶりに質問者の意図が全くわからん質問だな
124デフォルトの名無しさん:2006/03/20(月) 12:56:57
C++使いにはJavaっぽいと言われて良さそうだと思う人は少ないのではないかと思う。
125デフォルトの名無しさん:2006/03/20(月) 14:23:32
「Javaっぽい」という言葉が好意的に受けいれられるのはJava使いの間だけ!
126デフォルトの名無しさん:2006/03/20(月) 15:10:34
>>123-125
>C++使いにはJavaっぽいと言われて良さそうだと思う人は少ないのではないかと思う。
それもそうだ。了解です。
127デフォルトの名無しさん :2006/03/21(火) 03:39:05
まだ、C++初心者なんですが
参照で,アンパサンド 「 & 」 で宣言して
かつ、初期化が必要と知ったのですが
この参照という行為自体
何か、特別な意味合いがあるんでしょうか
学習していくうちに、必要性が出てくるのなら覚えておきたいですが
あまり必要性が無いなら、軽い知識として覚える程度で良いのでしょうか
あと、C言語なら、ポインタなら%pを使ってアドレスがみれて
%xなら16進数等、それぞれの変数に対する表現方法
があるのは自明の理だとおもいますが、C++では、また別の
構文が有るのでしょうか、初心者なので、屁みたいな質問かもしれませんが
できれば教えて頂きたいです
128デフォルトの名無しさん:2006/03/21(火) 04:05:12
参照を使うべきか、ポインタを使うべきかは、適材適所。両方同程度に使えるようにしておいた方がいい。

ポインタと参照で、おそらく一番違う点は、参照は「常にオブジェクトを指している」ことだ。
この制限があるので、より安全に使えることが期待できる。

int i = 1; // 整数型
int* ptr = &i; // 整数型へのポインタの初期化
int& ref = i; // 整数型への参照の初期化

*ptr = 2; // ポインタを介したアクセス
ref = 3; // 参照を介したアクセス

int* qtr; // qtrの指す先は不定
qtr = 0; // qtrはオブジェクトを指さない(ぬるぽ)
int& ref2; // エラー。参照先が指定されていない
int& ref3 = 0; // エラー。何も指さない参照は許されない
int& ref4 = *qtr; // 酷い例

上記例のように、参照の場合、初期化やアクセスの際に*や&などの記号がつかない。
参照元の完全な別名として扱うことができ、コードがすっきりする。

また、C++では関数は値渡しがデフォルトだが、効率の観点で関数呼び出し時にコピーを作りたくないことがある。
この場合、定数参照渡しが「非常に良く」登場する。
void func(const int& ref) { return ref*2; }

後半の構文云々はprintfの書式指定子のことかな?
出力ストリームへの書式指定は、C++ではマニピュレータを使う。
cout << setw(3) << hex << 25 << endl;
129デフォルトの名無しさん:2006/03/21(火) 06:59:47
C++なんかいらない、Cだけで十分
そう思っていた時期が俺にもありました
130デフォルトの名無しさん:2006/03/21(火) 07:10:05
ボクシングには蹴り技がある
そう思っていた時期が俺にもありました
131デフォルトの名無しさん:2006/03/21(火) 07:31:11
禿は自分の基本方針として「新機能をやたら増やしてユーザを喜ばす、ようなことは避けたい」と言っている
にもかかわらず、参照が TCPL の初版からあったのは "強い理由" があったからに他ならない
132デフォルトの名無しさん:2006/03/21(火) 08:38:24
newで確保してファイルから特定の文字列を可変長読み込むみたいなのを作ろうと思うんだけど
C++には動的配列拡張するCのreallocに対応する関数ってある?
133デフォルトの名無しさん:2006/03/21(火) 08:48:29
>>132
new で確保した領域を拡張する操作は無い。
かわりに std::vector を使うのが正解。
134デフォルトの名無しさん:2006/03/21(火) 08:55:28
struct C {
int x;
struct Y {
int y1, y2;
} y;
int z;
};
こういう構造体があるとき、C *p; に対して
printf("%d\n", p->x);
printf("%d\n", p->y.y1);
printf("%d\n", p->y.y2);
printf("%d\n", p->z);
を for 文で書けないでしょうか?
135デフォルトの名無しさん:2006/03/21(火) 09:03:03
>>134
いちおう書けるよ。余計なものがいっぱい付いてくるけど。
136デフォルトの名無しさん:2006/03/21(火) 09:04:47
余計なものって何さ
137135:2006/03/21(火) 09:05:37
つまり、止めとけってことね。元のソースで何が不満なのさ?
138デフォルトの名無しさん:2006/03/21(火) 09:14:53
>>136
size_t const offset_to_int[4] とか、
boost::function<int& (C&)> int_by_index[4] とか。

offsetof(C, y.y1) って有効だっけ?直接のメンバしかだめ?
139デフォルトの名無しさん:2006/03/21(火) 09:21:49
>>137
実際はメンバがもっと多くて処理も複数行に渡ってる、つまり
DoSomething1(p->Member1);
DoSomething2(p->Member1);
DoSomething1(p->Member2.SubMember1);
DoSomething2(p->Member2.SubMember1);
DoSomething1(p->Member2.SubMember2);
DoSomething2(p->Member2.SubMember2);
DoSomething1(p->Member3);
DoSomething2(p->Member3);
// ... まだまだ続く
みたいになっていて、一見しただけでは処理したいもの全部に
対して本当に処理しているのが分からないからです。これが例えば
int table[] = {C::Member1,C::Member2::SubMember1,C::Member2::SubMember2,...};
for (int i = 0; i < n; ++i) {
DoSometiong1(p.table[i]);
DoSometiong2(p.table[i]);
}
みたいに書ければ見通しがよくなるのですが。
140デフォルトの名無しさん:2006/03/21(火) 09:30:26
>>139
よしわかった。
じゃぁまずは offsetof 使ったやつを。
C が POD 限定になるうえに offsetof(C, y.y1) が怪しいが、
とりあえず >>134 の C についてコンパイルと実行はできた。

void print(C* p)
{
  static size_t const offset_to_int[4] = {
    offsetof(C, x),
    offsetof(C, y.y1),
    offsetof(C, y.y2),
    offsetof(C, z),
  };
  for(int i = 0; i < 4; ++i)
  {
    printf("%d\n", *reinterpret_cast<int*>(reinterpret_cast<char*>(p) + offset_to_int[i]));
  }
}
141デフォルトの名無しさん:2006/03/21(火) 09:36:52
142デフォルトの名無しさん:2006/03/21(火) 09:48:42
offsetof(C, y.y1) は offsetof(C, y) + offsetof(C::Y, y1) とすれば問題ない。
143デフォルトの名無しさん:2006/03/21(火) 10:03:33
無駄にBoost.Lambdaを使ってみる。
#include <iostream>
#include <boost/function.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/casts.hpp>
struct C {
int x;
    struct Y {
        int y1, y2;
    } y;
    int z;
};
int main()
{
    C c = {
        1,
        {2, 3},
        4
    };
    using boost::lambda::bind;
    using boost::lambda::_1;
    boost::function<int (const C&)> arr[] = {
        bind(&C::x, _1),
        bind(&C::Y::y1, bind(&C::y, _1)),
        bind(&C::Y::y2, bind(&C::y, _1)),
        bind(&C::z, _1),
    };
    for (int i = 0; i < 4; ++i)
        std::cout << arr[i](c) << std::endl;
    return 0;
}
144デフォルトの名無しさん:2006/03/21(火) 10:05:52
CがPODなら共用体を使うという手も使えるだろう。

union Hoge
{
    C Foo;
    int Bar[4]
};
145デフォルトの名無しさん:2006/03/21(火) 10:08:46
>>143
これを >>140 に最適化してくれるコンパイラがあれば神なんだが。

と思ってとりあえず iostream を cstdio に置き換えてから
gcc にアセンブリ吐かせてみたが、悶絶した。駄目だ。
146デフォルトの名無しさん:2006/03/21(火) 10:11:38
>>144
Hoge x に対して &x.Bar[1] == &x.Foo.y.y1 が成り立つと証明できる?
構造体のほうにはパディングが入る可能性があるからダメだと思うんだけど。
147デフォルトの名無しさん:2006/03/21(火) 10:15:22
アライメントを調整すればいいだけだろ
148デフォルトの名無しさん:2006/03/21(火) 10:26:58
そんなキモイコードは書きたくない。
149デフォルトの名無しさん:2006/03/21(火) 10:30:36
>>139
メンバー関数用意しろ。

150デフォルトの名無しさん:2006/03/21(火) 10:50:19
doxygenに食わせたら、構造体のメンバ一覧がperlで出るから、
それ使ってコード生成したら?
151デフォルトの名無しさん:2006/03/21(火) 10:53:26
巡回用のイテレータを作れば?
そうすりゃalgorithmも適用できるから2重にお得

#include<iostream>
struct C { 
    int x;struct Y {int y1, y2;} y;int z;
    struct iterator{
        C*c;int&(**pos)(C*);
        explicit iterator(C*c,int&(**pos)(C*)):c(c),pos(pos){}
        int&operator*(){return (*pos)(c);}iterator&operator++(){++pos;return*this;}
        friend bool operator!=(iterator a,iterator b){return a.c!=b.c||a.pos!=b.pos;}
    };
    iterator begin();
    iterator end();
}; 
namespace{int&Cx(C*c){return c->x;}int&Cy1(C*c){return c->y.y1;}
int&Cy2(C*c){return c->y.y2;}int&Cz(C*c){return c->z;}
int&(*table[])(C*)={Cx,Cy1,Cy2,Cz};}
C::iterator C::begin(){return C::iterator(this,table);}
C::iterator C::end(){return C::iterator(this,table+sizeof(table)/sizeof(table[0]));}
int main() 

    C c = {1,{2, 3},4 };
    C::iterator it = c.begin(),end=c.end();
    //for_each + ostream_iteratorでも可
    for (;it != end;++it) 
        std::cout << *it << std::endl; 
    return 0; 
152デフォルトの名無しさん:2006/03/21(火) 11:10:15
最近constのメリットがあんま見出せない気がするんだが・・
すでにビット的定数性のないクラスなんていくつも出てきたし、
スレッドセーフとか言うわけでもないし、なんのためにがんば
ってconstつけてんだかわかんねー。
唯一、
void f(const string& s)
とかで
operator動かせて、f("hoge")って呼べるくらいしか
思いつかない。




153デフォルトの名無しさん:2006/03/21(火) 11:23:12
>>152
うっかり書き換えてしまうのを防ぐことができるじゃないか。

いつの間にか const スレが落ちてるのに気づいた。
154デフォルトの名無しさん:2006/03/21(火) 11:26:14
>>152
void f(const string &s);
だと、
f(s);
としたときに、sの値が変わらないことが保証される。
「値が変わらない」の正確な意味は型によるけど、
たとえ内部表現が変わっても観測可能な振舞は変わらないように
const性が定義されてることを期待できる。
これで十分じゃないか?
155デフォルトの名無しさん:2006/03/21(火) 11:29:55
いやあ、まあそれはそうなんだがさ、それだけのためにちょっと
手間がかかりすぎる気がするなあと。
stlもconst_iteratorとかさ・・。もう疲れたよ。
全てつけるのやめるとすると、上の以外なんか問題ってあるん
だったっけ?
156デフォルトの名無しさん:2006/03/21(火) 11:36:31
>>155
静的な定数テーブルがプロセス間で共有できない。
または ROM に配置できない。
157デフォルトの名無しさん:2006/03/21(火) 11:37:34
>>153
constスレとカンマスレを偲ぶ人多いね。
良スレだったってことですね。
158デフォルトの名無しさん:2006/03/21(火) 11:43:44
>154
ほら、保障っつってもさ、const_cast程度で外されちゃうし、
大した保障じゃないなら、もう
void f(string &s);
でいいんじゃないのかなーとか思うんだよね。そうするとさ、
void getHoge() const{}
これは意味的定数性だからconstにして、メンバはmutableつけて
対策してと・・とか色々考えるのから開放されるしさ。
そもそもきっとconst導入した人は、ビット的定数性なんて問題を
想定してなかったような気がするし、そうするともう役目を終えてる
というか、なんかほとんど効力がない機能のような気がするんだよなあ。
159デフォルトの名無しさん:2006/03/21(火) 11:52:25
んじゃconstは気が向いた時に付ければいいってことで
160デフォルトの名無しさん:2006/03/21(火) 11:56:51
161デフォルトの名無しさん:2006/03/21(火) 12:00:43
ま、愚痴ってもしょうがないか
162デフォルトの名無しさん:2006/03/21(火) 12:35:25
>>152
値セマンティクスのクラスにはconstをしっかり考えてやるべきだけど、
参照セマンティクスのクラスはあまりconstを考える必要はない。

というのをどこかで読んだ覚えがある。
163デフォルトの名無しさん:2006/03/21(火) 14:28:47
>>149
>>151
C は自分で作ったクラスではないので、いじらずに済ませたいのです。
Interface Pattern はアリですが、もっとシンプルなのが無いかと思いまして。

>>150
C++ の範囲内でやる方法は無いですかねえ。
164デフォルトの名無しさん:2006/03/21(火) 14:38:23
>>163 140,143 は無視か?
165デフォルトの名無しさん:2006/03/21(火) 18:38:02
>158
>const_cast程度
程度じゃねえよ、const_castは実装のための最後の手段の1つで、
そうホイホイ使うような物じゃないだろ。

constは単純なread onlyインターフェイスを生成する手段の一つだと思ってる。
read onlyインターフェイスが要らないクラスなら、無くてもいいんじゃね。
166デフォルトの名無しさん:2006/03/21(火) 19:06:12
const_cast とタイプすると罪悪感に苛まれるな
167デフォルトの名無しさん:2006/03/21(火) 19:16:39
俺のやっていたことはすべて間違っていたのか?
と、途方にくれるな
168デフォルトの名無しさん:2006/03/21(火) 20:24:55
今のところ、幸いにもこういう風にしかconst_castは使ったことが無い。
class Hoge
{
public:
const_reference operator [](std::size_t i) const {/* 〜 */}
refernece operator [](std::size_t i) {return const_cast<reference>(static_cast<const Hoge&>(*this)[i]);}
};
169デフォルトの名無しさん:2006/03/21(火) 21:49:36
>>168
こっちのがよくね?
reference operator [](std::size_t i);
const_reference operator [](std::size_t i) const {return const_cast<Hoge&>(*this)[i];}
170デフォルトの名無しさん:2006/03/22(水) 00:14:24
int a[MAX] などと配列のメンバーを持つクラスにおいて、
コンストラクタで、メンバーイニシャライザで初期化するには
どうすればよいでしょうか?
171デフォルトの名無しさん:2006/03/22(水) 00:16:17
>>170
できません。
172デフォルトの名無しさん:2006/03/22(水) 00:17:10
ということは、コンストラクタの実装で、for で回す等して初期化するしかない
んですね。ありがとうございました。
173デフォルトの名無しさん:2006/03/22(水) 00:50:14
>158
ちょっと、言い方がおかしかったかも。
constの価値がないと言ってるんじゃなくて、概念的定数性の存在価値は
あるのかってことを言いたかった。
Java的に言うとimmutableパターンによるスレッドセーフなオブジェクトと
シャローコピー時のデータ汚染の回避みたいなメリットが、概念的定数性
だとmutableによって、当然どっちも失われるわけだから、苦労する意味は
いったいあるのか?みたいなことを言いたかった。
174デフォルトの名無しさん:2006/03/22(水) 01:14:34
int foo() {
bar();
{
 static int si = 123;
  return si;
}
}
みたいなC++の関数があるとして、si用のメモリが123に初期化されるのは
どのタイミングでしょうか?

1 プログラムが実行開始した瞬間
2 main関数到達前
3 foo関数初回呼び出し直後
4 変数siの存在するブロックに初回に入ろうとする時

くらいの候補があると思うのですが。手持ちのコンパイラでは1でしたが、
標準で保障されているのがどこまでかが知りたいです。
175デフォルトの名無しさん:2006/03/22(水) 01:17:00
>>173
その言い方だと mutable さえ使わなければ挙げてるメリットが得られるんだろ?
十分だと思うなぁ。
なんで mutable の使用が前提になってんの?
176デフォルトの名無しさん:2006/03/22(水) 01:24:29
標準仕様じゃ決まってないだろ。
大抵はデータセグメントに配置されて、プログラムロード時に初期値が設定されるんじゃねーの?

177デフォルトの名無しさん:2006/03/22(水) 01:26:41
>>174
POD 型のローカル static オブジェクトが定数式で初期化される場合、
プログラムが初めてブロックに入る前に初期化されていればいつでもいい。

6.7 -4-
ttp://www.kuzbass.ru/docs/isocpp/stmt.html#stmt.dcl
178174:2006/03/22(水) 01:32:41
>176,177
ども。クロスプラットフォームなコードを書いている関係で、「PODなロー
カルstaticオブジェクトの定数式による初期化」がスレッドセーフに行わ
れるかどうかを気にしているのですが、スレッドが絡むと標準仕様では何
ともいえないですかね・・・。
179デフォルトの名無しさん:2006/03/22(水) 01:54:22
>>178
大丈夫、どのスレッドかは兎も角、どれかのスレッドで最初に実行されるまでには
初期化されている。
まぁ、volatileつけないとどの道まともに扱えないわけだが。
180デフォルトの名無しさん:2006/03/22(水) 01:56:04
>>178
GCC 4.0 の変更点 http://gcc.gnu.org/gcc-4.0/changes.html に挙げられていた
リンクからたどった、関係ありそうな記事へのリンクを貼っておく。
http://www.codesourcery.com/cxx-abi/cxx-closed.html#G4
あんまりしっかり読んでないけど、とりあえず
いろいろがんばってる人たちが居るのはわかった。

「POD なローカル static オブジェクトの定数式による初期化」に限れば、
わざわざ初期化を遅らせるメリットも無いと思うんで、おおかたの実装で
グローバルなのといっしょにまとめて初期化されるだろうね。

ところでクロスプラットフォームでスレッドを扱うなら、使ってるスレッドライブラリに
ここらへんの問題に対処する道具があったりしないかな?
181デフォルトの名無しさん:2006/03/22(水) 02:04:36
>>179
いや、何の前提も加えずに大丈夫とは言えないだろう。
現行の規格ではスレッドについて何の言及も無いわけで、
規格に準拠したコンパイラがスレッドを考慮したコード生成を行うとは限らない。
182デフォルトの名無しさん:2006/03/22(水) 02:12:18
>179
そうだっけ?
確か大抵の実装は関数に入る際にフラグをチェックして
初回ならば、コンストラタを呼び・・みたいに展開されるので
マルチスレッドの場合はコンストラクタが2度呼び出されるので
危険だったような・・
だとすればPODの場合もアウトなので、その関数はまずシングル
スレッドで一度呼び出されていないとまずくなると想定していて、
俺は怖いのでそうしてる。
183182:2006/03/22(水) 02:20:06
いや、ごめん、実装依存か?
http://gcc.gnu.org/gcc-4.0/changes.html
The compiler now uses the library interface specified by the
C++ ABI for thread-safe initialization of function-scope static
variables. Most users should leave this alone, but embedded
programmers may want to disable this by specifying -fno-threadsafe-
statics for a small savings in code size.

gcc4.0はfunction-scope staticはthread-safeを保障しているみたい
VCはどうかな
184182:2006/03/22(水) 02:36:28
>175
概念的定数性ってメンバにキャッシュ処理的なことしてる場合に
GetHoge()とかがメンバを変えるけど、意味的にはconstって
ことだろ?
class A{public:
void GetHoge() const{a_ *= 2; return a_;}
mutable int a_;
};
でも、constにしたいからメンバをmutableにするって理解
だったが・・、なんか違うかな?
んで、結局GetHogeはスレッドセーフじゃないし、immutable
オブジェクトにもならないからメリットはなんだ?という
ことを考えたが。
185デフォルトの名無しさん:2006/03/22(水) 03:00:39
>>184
mutable を使えばそうなる。あたりまえ。
それは const の機能について「ほとんど効力がない」という理由にはならないだろ。

結局は、キャッシュや遅延評価を装備したオブジェクトから値を取り出す
メンバ関数に const 付けて mutable 使うか、非 const メンバ関数にしてしまうか
という2択で迷ってるだけじゃないの?
186デフォルトの名無しさん:2006/03/22(水) 04:29:01
>185
>それは const の機能について「ほとんど効力がない」という理由には
>ならないだろ。
いや、だからそれは173で訂正してると思う・・

> 結局は、キャッシュや遅延評価を装備したオブジェクトから値を取り出す
> メンバ関数に const 付けて mutable 使うか、非 const メンバ関数にしてしまうか
> という2択で迷ってるだけじゃないの?
Yes。けど、"ただ"と言えるほど簡単な話ではないと思う。(EffectiveC++
で筆者は両者の方法は哲学的問題と言ってるが)。そして、今のところ自他
ともスマートな解決方法は聞いたことがない。
185はどっちの立場でやってる?
187デフォルトの名無しさん:2006/03/22(水) 04:32:27
"ただ"→"だけ"
188デフォルトの名無しさん:2006/03/22(水) 05:10:02
constスレとカンマスレってどこにあるの?
189デフォルトの名無しさん:2006/03/22(水) 06:14:22
>188
多分,下の2つのスレのことかと思われ.いずれも dat 落ち.

【C++】 const だけでメシが3杯食えちゃうスレ
http://pc8.2ch.net/test/read.cgi/tech/1078193971/

【C】カンマ演算子を極めるスレ【C++】
http://pc8.2ch.net/test/read.cgi/tech/1112011590/
190デフォルトの名無しさん:2006/03/22(水) 07:21:33
>>179
>まぁ、volatileつけないとどの道まともに扱えないわけだが。
kwsk

191174:2006/03/22(水) 07:45:15
どもです。最近のg++なら(PODでなくても)スレッドセーフに初期化される
ので問題ないですね。しかし、MS/Sun/HP/Intel/..のコンパイラだとどうな
の?というのが気になっている&コンパイラ買えないという感じです。
local staticは諦めて、

static int si = 123;
int foo() {
 bar();
 return si;
}

にすればOKでしょうか。
192デフォルトの名無しさん:2006/03/22(水) 07:51:00
>>191 中だろうが外だろうが実装依存。
193174:2006/03/22(水) 08:02:43
>192
http://www.kuzbass.ru/docs/isocpp/basic.html#basic.start.init
を見るに外なら"static initialization"が行われるそうですが、
ほんとに実装依存?
194デフォルトの名無しさん:2006/03/22(水) 09:18:28
>>178
関数オブジェクトに汁
195174:2006/03/22(水) 09:26:19
>194
すみません、もうちょい具体的に・・・
196デフォルトの名無しさん:2006/03/22(水) 09:29:22
>>189ありがd
197デフォルトの名無しさん:2006/03/22(水) 09:56:18
198デフォルトの名無しさん:2006/03/22(水) 09:59:30
しつもんです、簡潔に
template <typename A,typename B>inline char *binary_pack(const std::map<A,B> &src,char *from)
{
 *((int*)from)=(int)src.size();
 from+=4;
 for(std::map<A,B>::const_iterator i=src.begin();i!=src.end();i++)
  from=binary_pack(*i,from);
 return from;
}
という関数を作ったのですがg++(gcc3.4.4/FC4)で通らなくて困ってます。
エラー内容はiteratorのiが定義されてないということらしいのですが、
VC++7やgcc3.2.4あたりでは通ったり(警告でる)します。
同じ関数名でいくつか似たような機能のものを複数多重定義してますが、
mapでないvectorのiterator作ろうとしてもエラーでてしまいます。
-fno-implicit-templatesのようなオプションも無駄でした
http://www.sra.co.jp/wingnut/gcc/gcc-j.html#Invoking%20GCCより

たぶんiteratorの定義方法が正確ではないのかなと思ってるんですが
エラーの対処方法詳しくわかる方居たらご教授願えないでしょうか?
199デフォルトの名無しさん:2006/03/22(水) 10:05:12
typename std::map<A,B>::const_iterator
かな
200198:2006/03/22(水) 10:10:32
ありがとうございます!
typenameつけたらwarningもでなくなり通るようになりました。
201デフォルトの名無しさん:2006/03/22(水) 10:10:41
>>198
本当にコンパイル通ったのか?
再帰の実引数 *i は map の const_iterator が指し示す先で
再帰の仮引数 src は map そのものへの参照やんけ
202デフォルトの名無しさん:2006/03/22(水) 10:22:05
そうじゃなくて、関数オブジェクトとスレッドセーフティの関係が知りたいってことだろ >>197

203デフォルトの名無しさん:2006/03/22(水) 10:33:43
>>201
多重定義だろ。
204デフォルトの名無しさん:2006/03/22(水) 10:54:35
STLportの便乗話だけど、VC7.1のビルドは特に何もしないで出来たが、
VC8のビルドは、configure.batを走らせてからでないとビルド出来ない。

多分もう誰でも知ってると思うけど、一応初心者用に書いておきます。
205デフォルトの名無しさん:2006/03/22(水) 10:54:56
誤爆シマスタ
206185:2006/03/22(水) 12:36:58
>>186
> いや、だからそれは173で訂正してると思う・・
ごめん。見落としてた。

よく考えると、概念的 const のせいで苦労が増すというのがおかしいと思う。

スレッドセーフが必要なら、どのみち値の算出(〜設定)に同期が要る。
クラスが内部でやらなければ利用者に責任が押し付けられることになる。

シャローコピーしたところで概念的に const でさえあればデータ汚染にはならない。
>>184 の例がまずいのは、繰り返し GetHoge() を呼び出すだけで値が変わっていくから。
一般的なキャッシュ、遅延評価の実装では他の非 const 操作が行われるまで
外部に返される値は変わらない。この場合、他に非 const 操作がなければ
Immutable オブジェクトとしての性質を満たし得るだろう。

先にインターフェースを考えて、実装段階でキャッシュが必要になることを考えると、
immutable を使った概念的 const も妥当だと思う。
207デフォルトの名無しさん:2006/03/22(水) 15:10:38
そろそろ標準でスレッドをサポートしてほしいな。
208デフォルトの名無しさん:2006/03/22(水) 15:20:22
重くなるからいらない
今の定義で十分に対応可能だし
209デフォルトの名無しさん:2006/03/22(水) 15:21:34
スレッドは一生無理でしょ
禿もそういってるし
210デフォルトの名無しさん:2006/03/22(水) 15:31:52
C++自体が多重仮想記憶を「サポートする」機能を持たないのと同じ
211デフォルトの名無しさん:2006/03/22(水) 19:01:38
マルチスレッドに対する挙動を仕様で決めてくれれば十分
212デフォルトの名無しさん:2006/03/22(水) 20:22:27
sizeofに詳しいサイト求む
213デフォルトの名無しさん:2006/03/22(水) 21:44:54
BCC5.6.4でこれをコンパイルすると、cが未定義だと怒られてしまいました。
共用体なので問題ないと思っていたのですが、何が問題なのでしょうか。


#include <iostream>
using namespace std;
union bits{
    bits(double n);
    void show_bits();
    double d;
    unsigned char c[sizeof(double)];
};
bits::bits(double n){
    d = n;
}
void show_bits(){
    int i, j;
    for(j = sizeof(double) - 1; j >= 0; j--){
        cout << "ビットパターン/Byte" << j << ": ";
        for(i = 128; i; i >>= 1)
            cout << i & c[j] ? "1" : "0";
        cout << endl;
    }
}
int main(){
    bits ob(1991.829);
    ob.show_bits();
    return 0;
}
214デフォルトの名無しさん:2006/03/22(水) 22:03:15
>>213
なんでshowのほうにbits::ねえんだよ
あとi&c[j]は括弧でくくれ、優先順位が違う
215デフォルトの名無しさん:2006/03/22(水) 22:11:38
>>214
すごい単純ミスですいません。
ありがとうございました。
216デフォルトの名無しさん:2006/03/22(水) 22:17:44
>207
boostじゃだめなの?
217デフォルトの名無しさん:2006/03/23(木) 02:30:02
volatile つけるとどういう効果があるんでしょうか?
218デフォルトの名無しさん:2006/03/23(木) 02:32:06
>>217
変数への読み書きが「副作用」とみなされ、最適化で削除されなくなる。
また、 const と同様にオーバーロードに使われる。
219デフォルトの名無しさん:2006/03/23(木) 02:37:42
>>217
ちなみに所謂cv修飾のvなのでconstがつけれるとこならどこにでもつけれる。

# c は const
220デフォルトの名無しさん:2006/03/23(木) 02:42:14
最適化で削除されたくない→volatileつける
と考えると、実際どういう場合につけるべきなのか
難しいですね。一時変数は別に不要だとわかりますが
クラスのメンバー変数は全部つけないといけなくなるのかな
221デフォルトの名無しさん:2006/03/23(木) 03:04:13
>>220
コードから見ていつ変わるかわからん変数やオブジェクトにつけるべし。

具体例をあげると複数のスレッドから変更される変数やオブジェクトとか
メモリマップドI/Oなんかに対してつける。こういった変数やオブジェクトに
アクセスする時に最適化が効いてるととんでもないことになる。

大変なことになる一例をあげると下のコードで hoge をどっかスレッドがfalseにしても
最適化が効いちゃってると無限ループになっちまう。これを避ける為には hoge を volatileで修飾すべし!

bool hoge = true;

void hige() {
 while(hoge);
}
222デフォルトの名無しさん:2006/03/23(木) 03:36:43
>>220
削除されるのは変数じゃなくて、変数への読み書きだぞ。
メンバー関数に全部つけるとか、ただの糞コードに他ならない。
223デフォルトの名無しさん:2006/03/23(木) 08:48:56
たとえばWin32のAPIとかconstのはずなのに宣言が
f(void* p);
ってふうになってるケースがあるからこれらを呼び出す時にconstキャストは多々つかいますわ。
224デフォルトの名無しさん:2006/03/23(木) 08:50:20
>>223
何言ってんの?
225デフォルトの名無しさん:2006/03/23(木) 09:04:30
ここでエスパー登場。

C 用に設計されたコールバックなどの汎用引数には
ほとんど void* が引数として使われるので、そこに
const T* を渡そうと思ったら const_cast が必要になる。

ってことだと思われ。
226デフォルトの名無しさん:2006/03/23(木) 10:07:45
>>220
>最適化で削除されたくない
       ^^^^
必ずしも削除じゃないよ
普通に文脈解釈したときの意味が変わるような削除まで無限に許しているわけじゃない
本当に厳密なタイミングが必要な箇所だとか、a -= 0; みたいに意味なさそうに見える箇所だとか、
本来ならアセンブラで書くような性格を含んでいるところに、取扱注意と書いておくだけ

>>222
メンバ関数全部に throw() をつけるたり
非静的メンバ関数全部に virtual をつけたり
基底指定子全部に public をつけたり
C++ ってデフォが糞なの結構あるね
227デフォルトの名無しさん:2006/03/23(木) 10:12:18
>>226
ではデフォルトで全ての変数をvolatile扱いしてほしいということですか。
228デフォルトの名無しさん:2006/03/23(木) 10:26:08
>>227
必要な箇所に必要なキーワードを置くことにいやも好きもない
俺はドライに割り切ってるが、糞という表現がでてきたんで言い出したらキリねえぞってだけ
229デフォルトの名無しさん:2006/03/23(木) 10:51:31
日本語でも勉強するか
230デフォルトの名無しさん:2006/03/23(木) 11:10:32
えんざんしおーばーろーど
231デフォルトの名無しさん:2006/03/23(木) 12:34:36
符号付き整数全てにsignedつけたり自動変数全部にautoつけたり
232デフォルトの名無しさん:2006/03/23(木) 15:24:49
今c++を独習しているのですが、
#include <iostream>
using namespace std;
template <class T>
class coord {
 T x,y;
public:
 coord(T i, T j)  { x=i; y=j; }
 friend ostream &operator<<(ostream &stream, coord ob);
 friend ostream &operator>>(istream &stream, coord &ob);
};
template <class T>
ostream &operator<<(ostream &stream, coord<T> ob)
{
 stream << ob.x << ' ' << ob.y << endl;
 return stream;
}
template <class T>
istream &operator>>(istream &stream, coord<T> &ob)
{
 stream >> ob.x >> ob.y;
 return stream;
}
int main()
{
 coord<int> i_ob(1,2);
 cout << i_ob << endl;
 return 0;
}

こういうコードコンパイルしたら「外部シンボルoperator<< ... が未解決」と怒られました。
どこを訂正すべきでしょうか?
233デフォルトの名無しさん:2006/03/23(木) 15:37:30
>>232
#include <iostream>
using namespace std;
template <class T> class coord;
template <class T> ostream &operator<<(ostream &, coord<T>);
template <class T> istream &operator>>(istream &, coord<T> &);

template <class T>
class coord {
  T x,y;
public:
  coord(T i, T j) { x=i; y=j; }
  friend ostream &operator<< <T>(ostream &stream, coord ob);
  friend istream &operator>> <T>(istream &stream, coord &ob);
};
234デフォルトの名無しさん:2006/03/23(木) 15:47:10
>>232
T x,y;
public:
coord(T i, T j) { x=i; y=j; }
- friend ostream &operator<<(ostream &stream, coord ob);
- friend ostream &operator>>(istream &stream, coord &ob);
+ template <typename U> friend ostream &operator<< (ostream &stream, coord <U> ob);
+ template <typename U> friend ostream &operator>> (istream &stream, coord <U> &ob);
};
-template <class T>
-ostream &operator<<(ostream &stream, coord<T> ob)
+template <typename U>
+ostream &operator<<(ostream &stream, coord<U> ob)
{
stream << ob.x << ' ' << ob.y << endl;
return stream;
}
-template <class T>
-istream &operator>>(istream &stream, coord<T> &ob)
+template <typename U>
+istream &operator>>(istream &stream, coord<U> &ob)
{
stream >> ob.x >> ob.y;
return stream;
235デフォルトの名無しさん:2006/03/23(木) 17:26:23
>>234
メンバテンプレート使うと、BCC5.8.1では「このコンテキストでは<<が
曖昧です」とか言われる。BCCのバグらしい。

gcc3.4.2(MinGW)、VC8ではちゃんと通る。
236デフォルトの名無しさん:2006/03/23(木) 19:58:46
どっちも一長一短だな

// --- fig1 ---------------------------
template <typename T> struct X {
template <typename U> friend void f(X<U>&)
{
X<int> a;
a.y = 0;
}
private:
int y;
};
main()
{
X<void> x;
f(x);
}
この場合、
・Borland 5.5.1 は private のみを問題視
・g++ 4.1.0 は X<void> で宣言された f と X<int> で宣言された f が曖昧と言ってくる
俺は g++ に賛成
237デフォルトの名無しさん:2006/03/23(木) 19:59:06
(>>236の続き)

// --- fig2 ---------------------------
template <typename T> struct X {
friend void g(X<T>&)
{
X<int> a;
a.y = 0;
}
};
main()
{
X<void> x;
g(x);
}
この場合、
・Borland 5.5.1 は X<void> で宣言した friend 権限は、X<int> には及ばないと言ってくる
・g++ は何も言ってこない
俺は Borland に賛成
238デフォルトの名無しさん:2006/03/23(木) 20:11:32
あ、y の宣言忘れてる・・・ でも、わかるよな?w
239デフォルトの名無しさん:2006/03/23(木) 21:22:47
>どっちも一長一短だな
fig 2の方は何がしたいか分からんのだが。
240デフォルトの名無しさん:2006/03/24(金) 00:22:11
>221
DQN発見..というのは言い過ぎかもしれないが..痛い。

別のスレッドがその変数に触るなら、mutexなりcritical sectionなり
で排他制御するのが正しい。もしそれを省略してlock-freeなアルゴ
リズムを採用したいのなら、volatileではなくメモリバリアを使え。
241デフォルトの名無しさん:2006/03/24(金) 00:24:55
メモリバリアとvolatileは用途が違うと思うんだが。
片方はコンパイラ向けで、片方はCPU向けでそ?
242240:2006/03/24(金) 00:32:28
メモリバリアは両用だよ。gccの__asm__の最後の引数に"memory"を
渡した場合について調べてみれ。
243デフォルトの名無しさん:2006/03/24(金) 00:44:59
============== ここまで読んだ ===================
244デフォルトの名無しさん:2006/03/24(金) 01:31:37
gccの、しかも、__asm__みたいな超特定言語固有な話をされても・・・
245デフォルトの名無しさん:2006/03/24(金) 01:36:20
>>240
volatile が必要になるようなケースで、volatile を書かずにメモリバリアを入れても駄目でそ。
っていうかメモリバリアってSMPじゃないと意味ないし。volatileはスレッドや割り込み処理でも
有効に使える・・というか正しく使わなくてはならない。
246デフォルトの名無しさん:2006/03/24(金) 01:40:46
そもそも最適化で消えちゃうのってコンパイラとして問題な希ガス
247デフォルトの名無しさん:2006/03/24(金) 01:49:01
>>240
DQN発見..というのは言い過ぎかもしれないが..痛い。

mutexなりcritical sectionなりを使ってもvolatileを使わなければ
コンパイラの最適化で無限ループになっても文句は言えない。
248デフォルトの名無しさん:2006/03/24(金) 02:13:16
>>247
>mutexなりcritical sectionなりを使ってもvolatileを使わなければ
>コンパイラの最適化で無限ループになっても文句は言えない。

え??
249デフォルトの名無しさん:2006/03/24(金) 02:55:29
>>247
さすがにグローバル変数の場合には volatile なしでも関数呼び出しの前には
値をストアするだろうし、後で参照すれば値をロードしなおすコードが出る出祖。

auuto 変数の場合にはコンパイルオプションによってはロードしなおさないコードが
でることもあるかもしれない。この場合には明示的な volatile が必要か。
250デフォルトの名無しさん:2006/03/24(金) 08:17:05
またvolatile厨か…
251デフォルトの名無しさん:2006/03/24(金) 13:45:39
vectorのような使い勝手で元から確保していた配列のサイズを
オーバーしてしまった時に自動でリサイズしてくれるような
クラスを作りたいのですが、

x[i] = x[i-1] + vx[i] * dt;

と言うような感じのコードを実行したときに、
「x[i]」でリサイズが必要になった場合、
「x[i-1]」の参照が無効になってしまうと言う状態になってしまいました。
なにかこう言った状態を解決する方法はないのでしょうか?
よろしくお願いします。
252デフォルトの名無しさん:2006/03/24(金) 13:49:02
>>251
operator [] の戻り値を参照型じゃなくて値型にしていれば
そういった状態にはならない。

配列クラスへのポインタとインデックスの組み合わせを持った
プロキシオブジェクトを返すことでも解決できるかもしれない。
253251:2006/03/24(金) 13:57:18
>>252
値の代入は何かほかの方法を用意しておくしかないということでしょうか?
プロキシオブジェクトについてはしらなかったので調べてみます。
ありがとうございました。
254デフォルトの名無しさん:2006/03/24(金) 14:06:31
>>249

bool hoge = true;

void hige() {
while(hoge);
}

大域スコープにあってもループ中にhogeを変更する明示的なコードが無いから>>221
↓のように置き換えるコンパイラがあってもおかしくない。つかstrength reduceとかあたりまえ。

void hige() {
if (hoge)
for (;;)
;
}

autoだと変数がレジスタにしか割り当てられない可能性高いけどそれはまた別の話。

はいはいワロスワロス
255デフォルトの名無しさん:2006/03/24(金) 14:09:48
どうやっても効率悪そうだな。
事前にresizeするか、↓じゃだめなの?

prev = x[i-1];
x[i] = prev + vx[i] * dt;
256デフォルトの名無しさん:2006/03/24(金) 14:18:17
>>255
それだったら、STLのvector使っても、あまり変わらないだろう。
257251:2006/03/24(金) 14:28:56
>>255
自分で使うだけなら事前にresizeするだけでもよかったんですが、
C言語もほとんどしらないような友人も使うので
できる限り単純にしておいておきたかったんですよね。
かといってデータの量もかなりあるので余り無駄なメモリも負担も増やせなくて…
258251:2006/03/24(金) 15:02:28
度々申し訳ないです。
一度も値が代入されていない変数の値を使う事は普通は無いと思うので、
リサイズする可能性があるのは代入演算子の左側の「x[i]」だけだと考えて、
x[i] = x[i-1] + vx[i] * dt;
と言うような命令があったときに「x[i]」でリサイズして
配列をdeleteするのを、次に「operator[]」が呼ばれた時にする
というのはありなのでしょうか?
なにか問題が起きそうな気もしなくもないですが
259デフォルトの名無しさん:2006/03/24(金) 15:03:50
副作用完了点をもう一度熟読した方がいいな。
260251:2006/03/24(金) 15:13:58
>>259
確かによくわかっていなかったです。
一度詳しく調べてみます。
261デフォルトの名無しさん:2006/03/24(金) 15:36:21
移植性がなくなってもよいのなら、>>251の言うような事はできるかも
しれんが、少なくとも式の評価順序について曖昧な部分は、その
処理系の説明書にも書いてないだろう。

規格はそこまで縛ってないのだから。自分で調べるというのならそれでも
いいのだが。
262デフォルトの名無しさん:2006/03/24(金) 15:50:24
STLでツリーって、どーつくるんですか?
263:2006/03/24(金) 15:55:15
Boost Graph Library を使う。
264デフォルトの名無しさん:2006/03/24(金) 15:56:59
「STL」でって言ってるだろうが、このカス
265デフォルトの名無しさん:2006/03/24(金) 15:58:11
>>261
operator=のPOD型に関する評価順序は右から左と決まっているので、
右辺を評価した後で左辺を評価した時に配列やvectorの参照アドレス
が変わるのがまずいって話でしょう。

あとoperator+とかは左から右なので、例えばx[i} + x[i + 1]という式が
あったとして、x[i + 1]がxの参照を変更してしまうような操作であった場合、
x[i]が参照で返されているとアクセスエラーが出る可能性があります。
だから>>252さんのおっしゃられる通り、値返しにすれば、アドレスが変化
しても問題がないように思います。
266デフォルトの名無しさん:2006/03/24(金) 16:01:17
配列でつくって、インデックスの差で構築するのが無難ですかー?
267デフォルトの名無しさん:2006/03/24(金) 16:04:33
>>265
いやいや、今の話はPOD型ではなくて、自前のクラスの話では。
まあクラスにしても同じなんだが。
268デフォルトの名無しさん:2006/03/24(金) 16:34:23
>>251
いっそstd::map使え。キーにstd::size_tを指定してしまえ。
269デフォルトの名無しさん:2006/03/24(金) 16:48:13
>>262
漏れは、各ノードに「親ノードへのポインタ」と「子ノードへのポインタのリスト」を持つようにした。
struct tree {
  tree* parent;
  std::list<tree*> children;
  T value;
};
実際にはstructではなくclassで、各メンバはprivateにした上でアクセサを定義。
イテレータとして
1. 子ノードイテレータ
 typedef std::list<tree*> children_type;
 typedef typename children_type::iterator children_iterator;
2. preorder_iterator(begin()、end()で先頭・末尾の次を取得でき、全ノードを前置順走査する)
3. postorder_iterator(rbegin()、rend()で先頭・末尾の次を取得でき、全ノードを後置順走査する)
を用意。tree::iteratorにpreorder_iteratorをtypedefしておく。
子ノードの追加はoperator+, +=、削除はoperator-, -=

これにストリーム入出力つけて300行くらい。でもコード見たらboost::iterator_facade使ってた。
270デフォルトの名無しさん:2006/03/24(金) 16:54:27
「STL」でって言ってるだろうが、このカス
271デフォルトの名無しさん:2006/03/24(金) 17:02:57
なんか変なのが混じってるようだが、マジレスすれば、

STLにツリーは用意されてません。
もしSTLっぽいツリーを実装したいなら、「tree.hh」でググるべし。
272デフォルトの名無しさん:2006/03/24(金) 17:03:16
>>269
始めはこの形を検討しました。
ただ怖いのは、ポインタが無効になることなんですよね。。

やっぱり配列かなぁ。。
Cらしくない。。
273デフォルトの名無しさん:2006/03/24(金) 17:05:53
>>271
おぉ。
面白そうなので、ソースを見てみます。
274デフォルトの名無しさん:2006/03/24(金) 17:10:04
>>273
ここが C++相談室 ならお前の言うことは正しい。
しかし、ここは 【初心者歓迎】C/C++室 Ver.25【環境依存OK】 なのであった。
275デフォルトの名無しさん:2006/03/24(金) 17:11:18
今後このスレは【初心者歓迎】C/C++室 Ver.25【環境依存OK】 となりますた
276デフォルトの名無しさん:2006/03/24(金) 17:15:39
うおっ
すまん。素でまちがえた。
277デフォルトの名無しさん:2006/03/24(金) 17:16:18
>>274
なにその誤爆系ギャグ
278デフォルトの名無しさん:2006/03/24(金) 17:17:20
>>272
ポインタが無効になる、というのはどういうこと?
見落としてるのかな。
279デフォルトの名無しさん:2006/03/24(金) 17:21:02
>>278
コピーした場合とかですね。
イテレータに詳しい方ならわかるはず。
280デフォルトの名無しさん:2006/03/24(金) 17:39:36
>>279
ううん…?
要素追加時にnew、要素削除時に子要素もろともdelete。
treeのデストラクタで全要素delete。
コピーコンストラクタでは構造通り全要素追加。
std::list<>で持っているのはノードへのポインタだから、deleteされるまで無効にはならないはず。
各イテレータは、直下の子要素追加・削除時に無効になるけれど、それはSTLでも同じことじゃないかい?

それとも見当はずれのことを言ってるのかな('A`)
281デフォルトの名無しさん:2006/03/24(金) 17:42:39
要素を管理しきれないなら木なんか作るな
282デフォルトの名無しさん:2006/03/24(金) 17:44:56
>>254
>関数呼び出しの前には値をストアするだろうし、後で参照すれば値をロードしなおす
 ^^^^^^^^^^^^^^^^^
目の不自由な人乙
それとも理解力ないのか?
283デフォルトの名無しさん:2006/03/24(金) 17:58:51
>>280
気にしていたのは、

tree<...> x, y;
xつりーを構築;
y = x; //yは有効なつりー?

とかです。

よく考えてみたら、yの木を根から再構築すればいいだけの話ですね。。
284デフォルトの名無しさん:2006/03/24(金) 18:00:56
>>283
日本語おかしいですね。
"y" -> "x"
もしくは、
"yの木を"->"yの木は"
285デフォルトの名無しさん:2006/03/24(金) 18:03:55
>>283
日本語おかしいですね。
"y" -> "x"
もしくは、
"yの木を"->"yの木は"
286デフォルトの名無しさん:2006/03/24(金) 22:47:25
251じゃないけど、勉強中なので練習がてら>>251の作ってみました

operator[]が返すのは参照型がダメだけど代入はできるようにする
っていうのを意識して内部クラス作ってみた

とりあえず最小限のことしか用意してませんが、なにかあれば添削とか批評お願いします
http://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/1706.txt

>>252
プロキシオブジェクトのことなんも知らず作ったけど、もしかしてこういうやつのこと?
287デフォルトの名無しさん:2006/03/24(金) 23:06:05
>>286
ひえーBCCだとコンパイルできない。
BCCぜってー変だよこれ。
VC7.1だと通るね。
288デフォルトの名無しさん:2006/03/24(金) 23:33:25
BCC なんて時代遅れだ。
289デフォルトの名無しさん:2006/03/24(金) 23:48:27
C++が読めないので教えください。
宣言の初期化みたいなんですけど、
コメントの 1、2、3 と return文 4 の
ところです。

#include <stdio.h>
class test {
public:
test() {};
~test() {};
static test* ins();
static test ins1;
static test* ins2;
static test* ins3;
};

test test::ins1; // 1
test* test::ins2 = test::ins(); // 2
test* test::ins3 = (test*)NULL; // 3

test* test::ins() {
return new test(); // 4
}
290デフォルトの名無しさん:2006/03/24(金) 23:53:18
>>289
1から3は静的変数の定義。
クラスの静的変数は、クラス内の宣言とは別にどこかcppファイルで定義が必要。
普通のグローバル変数がヘッダで宣言し、どこかで定義するのと同じこと。

2と3は初期化子を指定している。

4は動的にオブジェクトを作っている。誤解を恐れず言えばmallocのC++版と言ったところ。

これくらい自分で何とかしろよ。
291デフォルトの名無しさん:2006/03/24(金) 23:56:43
>> 290
ありがとうございます。感謝です。
C++は暗号みたいで難しいです。
292デフォルトの名無しさん:2006/03/25(土) 00:18:05
ついでに言うと、こんなコード参考にしちゃいかんよ。
このコードだとメモリリークする危険がありますな。
293デフォルトの名無しさん:2006/03/25(土) 00:30:20
289ではないけど

freeがないからリークの可能性って事

C言語はまだ良く分からないけど
294由美子:2006/03/25(土) 00:32:26
コマンドプロンプト-bcc32 kon.c
NTVDM CPUは不正命令を検出しました。
CS:270c IP:0103 OP:63 3a 5C 42 6f アプリケーションを終了するには[閉じる]を選んでください。
と表示され.odjファイルしか作れません。三つファイルが出来るのですよね?
かれこれ2時間格闘しています。
誰か、何が悪いのかわかる方いらっしゃいますか?
よろしくお願いします。かなりの初心者で申し訳ありません
295デフォルトの名無しさん:2006/03/25(土) 00:57:53
core吐いてないか?
それを見てなんとか汁
296デフォルトの名無しさん:2006/03/25(土) 01:21:03
本物のプログラマはコアダンプを読める。
297デフォルトの名無しさん:2006/03/25(土) 01:58:29
本物のプログラマはechoとリダイレクトでプログラムする。
298由美子:2006/03/25(土) 02:44:13
core?ですか?わかりません。初心者で申し訳ないです。どーやって調べれば見つかりますか?
ホントお願いします。泣
299デフォルトの名無しさん:2006/03/25(土) 02:47:59
>>265
'=' も '+' も評価順序は決まってないよ。
300デフォルトの名無しさん:2006/03/25(土) 02:54:45
NTVDM つってるのに core かよ・・・ 何ともご立派なセンセイだな
301デフォルトの名無しさん:2006/03/25(土) 03:10:13
あるクラスのインスタンスが、状態遷移を持っていて、
その状態によって、使えるメソッドが決まる、という設計は
やっぱ糞かなw
302デフォルトの名無しさん:2006/03/25(土) 03:11:51
>>301
糞かどうかはわからないが、バグの元になることは確かだ。
303デフォルトの名無しさん:2006/03/25(土) 05:51:56
asshole->*
304デフォルトの名無しさん :2006/03/25(土) 09:40:59
屁みたいな質問内容だと思うけど出来れば教えてください
以下のソースで動かしました
#include <iostream>
using namespace std;
class Test{
public:
char *ary;void print(char *ary);Test(char *ary);~Test();};
Test::Test(char *ary){cout << "コンストラクタ\n";cout << ary << '\n';}
Test::~Test(){cout << "デスクトラクタ\n";cout << ary << '\n';}
void print(Test *obj){obj->ary = "print()\n";}
int main(){Test obj("Hello");print(&obj);return 0;}
で、デスクトラクタは、オブジェクト破棄の後に出る関数と捉えているんですが
結果、print()という関数の前にデスクトラクタが出てきました
objが破棄されたにもかかわらず、objの参照渡しがなされてるようで
不思議です。まだまだクズの初心者なんで、学習量が少ないんですが
出来れば教えてください
305デフォルトの名無しさん:2006/03/25(土) 09:54:22
>>304
>結果、print()という関数の前にデスクトラクタが出てきました
どうやってこれを確認した?
306デフォルトの名無しさん:2006/03/25(土) 09:57:01
>>304
コンストラクタ
Hello
デスクトラクタ
print()
と出力されて何も問題ないようだが。
ちなみにprint関数の中では代入しているだけで画面への出力はぜんぜん行っていないからな。
307デフォルトの名無しさん:2006/03/25(土) 11:39:15
>>288
何を言う!BCCと言っても、現時点では最新バージョンの5.8.1だぞ!
(タイムスタンプ 05-12-01 10:01)

・・・・・と言ってもむなしいだけだよな。氏ねよBCC・・・・
308デフォルトの名無しさん:2006/03/25(土) 16:32:58
早見優!
309デフォルトの名無しさん:2006/03/25(土) 19:10:32
>>304
挙動については>>306だと思うが、気になったので老婆心から一言言わせてくれ。
クラスTestのメンバにvoid print(char* ary)があり、かつ、クラス外にもvoid print(char* ary)がある。
こういうケースでは、クラスメンバの方だけを使う方がいいと思う。
あと、メンバ変数char* aryと、コンストラクタの引数char* aryが同名だけど、ちゃんと混乱せず使えてる?
挙動がわからない状況では、まぎらわしい記述は避けた方がいいよ。
310デフォルトの名無しさん:2006/03/25(土) 19:11:40
>>309の「クラスメンバの方だけを使う方がいい」というのは無視してくれ。
すまんこ
311304:2006/03/25(土) 20:34:31
まだ、勉強中なので、混乱した状態での把握をしておこう
と思っています。さすがに、長いプログラム書くときに
こんな同名の変数やら、メンバやらは区別しようと
思ってます。
312デフォルトの名無しさん:2006/03/25(土) 21:03:46
>>304
これやってみな
main()
{
cout << "--------------" << endl;
Test obj("Hello");
cout << "--------------" << endl;
print(&obj);
cout << "--------------" << endl;
}
313デフォルトの名無しさん:2006/03/25(土) 21:05:57
★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆
     筑紫23の偏向報道にはもう我慢できない!!!
   スポンサー「キリン」に対して抗議の不買運動実施中!!!
★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆

一向に偏向報道をやめない筑紫23に対して抗議の不買運動を実施中です。

・偏向報道って具体的にどんななの?
→★TBSで放送された、ナヌムの家の動画
  --- 動画抜粋 ---
  動画1
  http://youtube.com/watch?v=AlPQUhb7GDI
  動画2
  http://youtube.com/watch?v=lHEDn2CMTYg
  そんなに長くありません。1回見ればその悪質さが理解できます。
(これは一部です。本スレにすべてのリンクがあります)

・なんで不買?直接抗議すれば?
→電話やEメールなどで抗議では、聞き流されるか不遜な応対をされます。
 不買運動は元法務大臣も推奨する合法的な活動です。

・何でキリンだけなの?
→みんなでまとまって一つの企業に対してやらないと力が分散し、あまり効果が望めません。
 特に偏向・捏造・隠蔽の酷かった「ナヌムの家」の回のスポンサーであったキリンに白羽の矢が立っただけです。

 詳しくは本スレまで
【キリンから】筑紫23偏向報道・スポンサーに抗議の不買★30
http://live22x.2ch.net/test/read.cgi/news/1143280975/

314デフォルトの名無しさん:2006/03/25(土) 22:12:11
>>311
> こんな同名の変数やら、メンバやらは区別しようと
これは、ちょっと違う
変数名は別に同じでも構わない
初心者は別だが
315デフォルトの名無しさん:2006/03/25(土) 22:38:27
あるクラス定義ヘッダ中で、

int getHoge(int a) const;

とかかれていた所があったのですが、このconst はどういう意味なのでしょうか?
316デフォルトの名無しさん:2006/03/25(土) 22:39:24
クラスのメンバ変数を書き換えません。
317デフォルトの名無しさん:2006/03/25(土) 22:40:56
俺も数日前同じ質問したな
おまいらありがと
318デフォルトの名無しさん:2006/03/25(土) 22:43:17
static int getHoge(int a);
とどう違うの?
319デフォルトの名無しさん:2006/03/25(土) 22:47:00
比較するなんて考えたくないほど全く違う
320デフォルトの名無しさん:2006/03/25(土) 23:35:42
>>318
端的に言えばthisポインタの有無。

だめな説明だな、これじゃ。
321デフォルトの名無しさん:2006/03/25(土) 23:36:57
>>318だとgetHoge()の中でメンバー変数に一切アクセスできない。
>>315だとgetHoge()の中でメンバー変数を読むことだけはできる。
322デフォルトの名無しさん:2006/03/26(日) 00:40:35
ヘッダファイルにインクルードしたくないから
ポインタでかまわない場合は、

class CFoo;

class CAAA
{

protected:
CFoo *pFoo;
};

こんなふうによくやりますけど、
このCFooってクラスがnamespace付きの場合って、
無理なんでしょうか。




class hoge::CFoo;

class CAAA
{

protected:
hoge::CFoo *pFoo;
};


こういうのは怒られてしまうんですけど、
ヘッダにインクルードする以外手はないんでしょうか
323デフォルトの名無しさん:2006/03/26(日) 00:44:41
namespace hoge
{
class CFoo;
}

じゃだめか?
324デフォルトの名無しさん:2006/03/26(日) 02:50:33
素朴な疑問だが、コンストラクタが複数ある場合に初期化リストって
めんどくね?
俺はパフォーマンス多少悪くなるけど、共通関数作って呼んじゃってる
けど、みんなどうしてる?
325デフォルトの名無しさん:2006/03/26(日) 04:52:05
そうしてる。
326デフォルトの名無しさん:2006/03/26(日) 04:53:24
がんばって初期化リスト使う

極まれにマクロつかったりする
327デフォルトの名無しさん:2006/03/26(日) 05:48:12
>>324
メンバ多すぎるんじゃね?
private にネストしたクラス作るとうまくいったりする。
328デフォルトの名無しさん:2006/03/26(日) 07:57:58
>>324
クラスをインターフェイスと実装に分離し、非公開継承する
329デフォルトの名無しさん:2006/03/26(日) 08:34:46
pimpl
330デフォルトの名無しさん:2006/03/26(日) 10:41:17
>>324
どんなにきつくても悪魔のささやきには負けない
331デフォルトの名無しさん:2006/03/26(日) 12:16:20
俺はデータブロックとみなすかインターフェースとみなすかで
早めにPODとクラスに分けちゃってクラスの書き方は速度をあんまり考えてない。
332デフォルトの名無しさん:2006/03/26(日) 12:53:50
>>331 お前さん、 POD の意味わかってる?
333デフォルトの名無しさん:2006/03/26(日) 12:56:21
plain old dataだろ?ハゲを舐めるなよ
334デフォルトの名無しさん:2006/03/26(日) 12:57:01
そうなると >>331 の意味がわからんわけだが。
335デフォルトの名無しさん:2006/03/26(日) 13:04:57
別にフサフサはムリして理解しようとしなくていいぞっと
336デフォルトの名無しさん:2006/03/26(日) 13:08:17
いや、ハゲが言葉の意味を誤解してるんだろ。
struct S { std::string s; }; この S はデータブロックだが POD じゃないぞ。
337デフォルトの名無しさん:2006/03/26(日) 13:11:13
>>321ありがdd
338デフォルトの名無しさん:2006/03/26(日) 14:23:56
>>323

おお、なるほど!!
ありが`

じゃあついでにもう1こ。

クラス内クラスを別ヘッダから宣言だけしたい場合はどうすればよいんでしょ。

class CFile
{
class CHandle
{
int a;
};
};

こういうクラスがあったとして、CHandleを別のヘッダで


class CFile::CHandle;

ってやると怒られてしまいますが、
これって、

class CFile
{
class CHandle;
};

こんなことやってもダメですよね?
339デフォルトの名無しさん:2006/03/26(日) 14:31:51
>>338
その問題は避けられないので、ネストされたクラスは
インターフェースに使わないほうがいい。
逆に言うと、インターフェースに使うクラスは
ネストされたクラスにしないほうがいい。
340デフォルトの名無しさん:2006/03/26(日) 20:40:49
includeのヘッダファイルなどの書き方について
よくわからないところがあったので質問させてもらいました。
「*.h」というようなファイルには極端な話し
外部のファイルからアクセスする必要があって、
実体の無い物のみ書き込むと言うような考え方で良いのでしょうか?
またサブフォルダなどを使ってはいけないと言う話しをどこかで聞きました。
#include "./test/test.h"
#include "../test.h"
などとすると問題が起きることがあるのでしょうか?
ヘッダファイルの中では極力インクルードを使わないようにした方が良い
なんて言う話しも聞いたことがあります。
なにかこう言ったようなやってはいけない的な事があれば
教えてもらえませんでしょうか?
基本的な質問で申し訳ないですが、よろしくお願いします。
341デフォルトの名無しさん:2006/03/26(日) 20:50:52
Cの時代なら、基本的にはヘッダファイルにはプロトタイプ宣言を、
*.c ファイルには関数の定義を書くんだよ、って言えたんだけどなぁ。
クラスの定義はヘッダファイルに書くし、テンプレートの定義も
ヘッダファイルに書くし、ヘッダファイルって大活躍だよね。

ごめん、ぜんぜん質問の答えになってなかった。寝るわ。
342デフォルトの名無しさん:2006/03/26(日) 21:09:00
>>341
確かに言われてみればクラスやテンプレートを勉強し始めてから
よくわからなくなってきたような気がします。
ありがとうございました、お疲れさまです。
343デフォルトの名無しさん:2006/03/26(日) 22:44:36
>>340
ヘッダの変更は利用側の再コンパイルを必要とするので、
内容は必要最小限にしておいたほうがいい。

ヘッダファイルの検索方法は標準で定義されていないので
コンパイラ間で移植を行うときに問題になることがある。
個人的には、 . や .. などソースファイルの位置に依存する書き方は
問題になりやすいのでお勧めしない。
ただ、コンパイルオプションの設定でどうにかなることがほとんど。

ヘッダファイルの中でのインクルードは依存関係を累積的に増やす事になる。
これも必要最小限にするべきだろう。
344デフォルトの名無しさん:2006/03/26(日) 23:33:12
 public:
typedef enum A {
a,
b,
c,
: (20個ぐらい続く)
} TypeA;


こういうクラスの中にtypedefされたenum定義とかって、別のヘッダファイルにしておいて
public:
include A.h;

みたいにかけないですかね?
345デフォルトの名無しさん:2006/03/26(日) 23:35:22
>>344 かけるよ。
346デフォルトの名無しさん:2006/03/26(日) 23:35:27
>>344
普通に書けるよ。
class something {
public:
#include "A.h"
};
347デフォルトの名無しさん:2006/03/26(日) 23:59:21
#include <a.h>で出来るだろ。
348344:2006/03/27(月) 00:04:54
orz
349デフォルトの名無しさん:2006/03/27(月) 00:37:40
class A, B, C というのがあり、BもCもAを継承するのですが、Aの一部の
メソッドは、Bの方には継承したくありません。こういう場合、一般的にはどうするのが
うまい設計でしょうか?

単純にAの一部のメソッドを別クラス(A’)にしてCの方は、AとA’
を多重継承させるのが簡単かと思いますが、この場合A’は引数にAの
メンバ変数を取る単なる関数の集合体になります。まぁこれでもいいの
ですが、何かもうちょっとオブジェクト指向的な?よい方法はありますか?
350デフォルトの名無しさん:2006/03/27(月) 00:43:05
>>349
> この場合A’は引数にAのメンバ変数を取る単なる関数の集合体になります
ここの意味がわからん。

不満が無いならそれでいいだろう。
何が不満なのかわかるように書いてくれれば、
回避方法もあるかもしれんが。
351デフォルトの名無しさん:2006/03/27(月) 00:45:07
>>349
Aの一部のメソッドを外したものをBaseAとして定義してその一部のメソッドだけの集合をOptAにつっこんでCはOptAを継承してBはBaseAを継承じゃだめなのか?
というかAが基底になりきってないだけじゃないの?

ライブラリ提供のAだってならどうしようもないけどな。
352デフォルトの名無しさん:2006/03/27(月) 00:49:14
>>349
「オブジェクト指向的」に言うと、Aの持つインターフェースを全て持たないなら
BはAをpublic継承すべきではない。
C++の観点から言うと、usingを使って継承されたメンバのpublic/privateを自由に変更できる。
353デフォルトの名無しさん:2006/03/27(月) 00:49:29
BでAから継承したくない関数と同名で引数を変えたメンバ関数を
プライベートに宣言しとくとか
354デフォルトの名無しさん:2006/03/27(月) 00:51:56
>>352
>C++の観点から言うと、usingを使って継承されたメンバのpublic/privateを自由に変更できる。
できなくね?
355デフォルトの名無しさん:2006/03/27(月) 00:55:02
>>354
#include <iostream>

struct a
{
  void f(){std::cout << "f\n";}
  void g(){std::cout << "g\n";}
};

struct b : public a
{
private:
  using a::f;
};

int main()
{
  b x;
  x.f(); /* エラー: b::fはprivate */
  ((a &)x).f(); /* ok */
}
356デフォルトの名無しさん:2006/03/27(月) 00:58:14
>>355 うは、使えねぇ。
357354:2006/03/27(月) 00:59:04
>>355
g++ 3.3.5では通るのであった
355の方が自然だとは思うけど,さて規格ではどっち?
358349:2006/03/27(月) 01:01:09
みなさんアドバイスありがとうございます。
その中で、

>>352
>「オブジェクト指向的」に言うと、Aの持つインターフェースを全て持たないなら
BはAをpublic継承すべきではない。

まさにここをお聞きしたかったのですが、全てもたないけど一部は持つ(その一部
は実装が共通のメソッド)
という場合はどのようにすべきなのでしょう? 個人的にはこれってmix-inの問題
なのかなと思ったりするのですが。う〜ん
359349:2006/03/27(月) 01:02:17
あ、public継承にしなければいいのかな
360デフォルトの名無しさん:2006/03/27(月) 01:03:04
>>357
g++3.5.4
test.cpp: In function `int main()':
test.cpp:5: error: `void a::f()' is inaccessible
test.cpp:18: error: within this context
361デフォルトの名無しさん:2006/03/27(月) 01:03:36
>>349
そもそもなんでAを継承したい?
362360:2006/03/27(月) 01:04:08
3.4.5ね。
363デフォルトの名無しさん:2006/03/27(月) 01:04:53
>>358
どうするべきかって言ったら、きっちりインターフェースを切るべきに決まってるだろ。
何が不満なのかわかんないままだし。
364デフォルトの名無しさん:2006/03/27(月) 01:05:36
>>343
なるほど・・・ありがとうございます。
参考になりました。
365デフォルトの名無しさん:2006/03/27(月) 09:59:23
なんだっけ。
「ペンギンは鳥。鳥は空を飛べる。従ってペンギンは空を飛べる。あれれ?」問題だっけ。
鳥クラスにfly()メソッドがあり、鳥クラスを継承したペンギンはfly()が呼び出せる。
fly()をprivateにしたり例外投げたりすることで、ペンギンは空を飛べなくなる。
しかし、これは、ペンギンは空を飛べるが、空を飛ぼうとしたら必ず失敗する、ということにすぎない。
それが嫌なら、flyable_birdクラスとnon_flyable_birdクラスあたりに分離する。

というのをどこかで昔読んだ。
366デフォルトの名無しさん:2006/03/27(月) 10:58:14
>空を飛ぼうとしたら必ず失敗する、ということにすぎない。

実際、そうだけどね
バージョン化したプログラムに退化器官はつきものだし
退化ではなくもともと翼のない鳥なんておかしなものを後付で作るほうがどうかしてるよ
367デフォルトの名無しさん:2006/03/27(月) 11:19:42
>>365
なんかすごい納得。いいなその説明。
メモっとこ。
368デフォルトの名無しさん:2006/03/27(月) 11:28:56
飛ぶ概念クラスを作ってその鳥クラスに継承させるか否か決めればいんじゃね?
369デフォルトの名無しさん:2006/03/27(月) 11:32:40
そこで、テンプレートですよ。

struct typelist_tag{};

template< typename Signature > struct inherits;
template< typename T1 >
struct inherits< typelist_tag ( T1 ) > : public T1 {};
...

/* 鳥テンプレート */
template< class Polices >
class bird : public inherits< Polices >
{
 ...
};

struct flyable { virtual void fly()=0; };
struct swimable { virtual void swim()=0; };

// カラス
class crow : public bird< typelist_tag( flyable ) >
{
 /* fly を実装するとか */ ...
};

// ペンギン
class penguin : public bird< typelist_tag( swimable ) >
{
 /* swim を実装するとか */ ...
};
370デフォルトの名無しさん:2006/03/27(月) 11:40:33
それって多重継承で良くね?
// 鳥
class bird
{
 ...
}; 

struct flyable { virtual void fly()=0; }; 
struct swimable { virtual void swim()=0; }; 

// カラス 
class crow : public bird,public flyable

    /* fly を実装するとか */ ... 
}; 

// ペンギン 
class penguin : public bird,public swimable

    /* swim を実装するとか */ ... 
};
371デフォルトの名無しさん:2006/03/27(月) 11:41:08
>>368の言うとおり、「鳥は空を飛べる」の時点で間違ってるんだけどな
372デフォルトの名無しさん:2006/03/27(月) 11:45:25
あの鳥はまだうまく飛べないけど〜
いつかは風を切って知る〜
373デフォルトの名無しさん:2006/03/27(月) 12:01:20
>>372
空気嫁
374デフォルトの名無しさん:2006/03/27(月) 12:04:30
空を〜
飛べるはず〜
375デフォルトの名無しさん:2006/03/27(月) 12:04:58
>>365
EffectiveC++の
「publicに継承するときはis-a関係にあるか確認しよう」
に出てた。これが最初かしらんけど。

   bird
  /   |
flying non flying
      |
     penguin

こんな感じででてたね。
私自身、この設計が間違ってるとは思わないけど、
本の中で、例を出すにはいい解説だったと思うよ
376デフォルトの名無しさん:2006/03/27(月) 13:15:25
class hoge{
hoge();
}
hoge::hoge(){
class piyo{
piyo();
int piyovalue;
}
}
piyo::piyo(){
piyovalue=0;
}

見たいな事できる?
変なところがあったらダメだし求む。
377デフォルトの名無しさん:2006/03/27(月) 13:28:15
>>376
試すって発想は無いのか?
378デフォルトの名無しさん:2006/03/27(月) 13:31:04
無いが何か?
379デフォルトの名無しさん:2006/03/27(月) 13:35:54
なら回線切って首吊って氏ね
380デフォルトの名無しさん:2006/03/27(月) 13:39:59
お前が氏ね
381デフォルトの名無しさん:2006/03/27(月) 14:14:37
みんなはさーん
382デフォルトの名無しさん:2006/03/27(月) 17:07:53
>>379
相談のマナーがなってなけりゃスルーでええやん。
383デフォルトの名無しさん:2006/03/27(月) 17:46:41
>>376
どうでもいいけど、classの宣言・定義は、ブロック {} のあとに ; が必要だ。
piyoのコンストラクタはprivateなので、
hogeと明示的にfriend関係にするか、piyoをpublic継承しないと
このままではpiyoのインスタンスを生成できない。
コンストラクタで例外が投げられないよう気を付けておく。
384デフォルトの名無しさん:2006/03/27(月) 18:07:56
newした配列をdeleatするときに、deleat [] arrey;といった様に、これからdeleatするオブジェクトを明示的に指定しなければならない理由とは何でしょうか。
もしくは、どんなオブジェクトでも無差別に開放するスマートな方法はありますか?
385デフォルトの名無しさん:2006/03/27(月) 18:20:27
C++でオブジェクトの配列は忌み子だから、おとなしく
std::vectorでもつかっときなさい
386デフォルトの名無しさん:2006/03/27(月) 18:23:17
え?じゃあ文字列はどうすればいいんですか?
これも有効な方法があるんですか?
387デフォルトの名無しさん:2006/03/27(月) 18:33:04
文字列にはstd::stringがあるだろう。
388デフォルトの名無しさん:2006/03/27(月) 18:33:10
>>384
通常は auto を使えば構築と破壊の対をコンパイラに作ってもらえる
それをわざわざ違う方法で扱うからには構築と破壊の対を特殊な形にする動機が必ずあるはず

よって、この質問はシュールと言わざるを得ない
>もしくは、どんなオブジェクトでも無差別に開放するスマートな方法はありますか?
389デフォルトの名無しさん:2006/03/27(月) 18:41:17
>>388
無差別にオブジェクトを削除したければ、ステートメントブロックを作ってその中に記述すれば良いんですか?
390デフォルトの名無しさん:2006/03/27(月) 18:46:54
>>389
詩的な表現をされている部分の真意を測りかねるが
ブロックからの逸脱を削除と解釈してはならないオブジェクトを指定する方法が new や static だ
391デフォルトの名無しさん:2006/03/27(月) 19:08:05
autoだと(ブロックの中で)無差別に殺す事が出来る
でもスマートじゃない。
392デフォルトの名無しさん:2006/03/27(月) 19:22:02
>でもスマートじゃない。

え???
393デフォルトの名無しさん:2006/03/27(月) 19:37:21
しゃべり過ぎは禁物
このへんでやめとこう
394デフォルトの名無しさん:2006/03/27(月) 20:41:52
まとめると、オブジェクトはステートメントブロック内でしか生きられないから、deleatとかを使って
コツコツオブジェクトを殺すんじゃなくて、ステートメントブロックを活用して一気にオブジェクトを殺せば良いと。
でもそれだと複雑なコードが組めないし、トリッキーになるから素直にdeleatするか、この話はこのへんで止めておこうと。
395デフォルトの名無しさん:2006/03/27(月) 21:04:42
deleteも綴れない無能は何言っても無駄
396デフォルトの名無しさん:2006/03/27(月) 21:07:54
deleatと打ちたくなる気もわからなくはない
397デフォルトの名無しさん:2006/03/27(月) 21:20:01
そこは敢えてスルーしてたのに…
398デフォルトの名無しさん:2006/03/27(月) 21:30:45
くだらんつっこみで、流れを壊してる奴、空気読め。
399デフォルトの名無しさん:2006/03/27(月) 21:34:09
このへんでやめておこう

という気持ちもわかるが、最後の締めがdeleatじゃねぇ・・・
400デフォルトの名無しさん:2006/03/27(月) 22:59:54
女にもてない奴は、空気が読めない。
401デフォルトの名無しさん:2006/03/27(月) 23:12:28
逆も成り立つ。
空気が読めない奴は、女にもてない。
402デフォルトの名無しさん:2006/03/27(月) 23:15:10
う ほ や ら な い か と言われた俺は?
403デフォルトの名無しさん:2006/03/27(月) 23:17:09
>>400は多くの場合誤り
>>401はまぁまぁ正しい
404デフォルトの名無しさん:2006/03/28(火) 00:01:41
>>402
同類なので憐れんであげる。             orz
405デフォルトの名無しさん:2006/03/28(火) 01:16:25
同類憐れみの令
406デフォルトの名無しさん:2006/03/28(火) 02:20:47
.exe
407デフォルトの名無しさん:2006/03/28(火) 05:20:35
>>384
配列arrayの先頭アドレスは、しばしばポインタで表される。

あるポインタ変数が与えられたとき、それはオブジェクトへのポインタを指すのか?
T* X = new T;
それとも、配列の先頭アドレスなのか?
int array[N];
int* Y = &array[0];
両者を区別することは難しい。
そこで、オブジェクト用のdeleteと、配列用のdeleteを用意して、
判断をプログラマにまかせているのだと思われ。
delete X;
delete[] Y;
408デフォルトの名無しさん:2006/03/28(火) 05:22:42
delete p == delete[1] p は結果的にボツったけど案は出てたね
409デフォルトの名無しさん:2006/03/28(火) 15:47:17
C++で
エラー処理を一箇所でまとめたいとき
try ~ catchって使っていいの?
gotoや、do{ break }while(0);とか使うべき?

エラーと例外は別物とか聞いたし
410デフォルトの名無しさん:2006/03/28(火) 15:59:56
ケースバイケース
411デフォルトの名無しさん:2006/03/28(火) 16:02:28
>>409
まさにそのために例外がある。

ただし、例外を使うのは例外的な状況に限ったほうがいい。
412デフォルトの名無しさん:2006/03/28(火) 16:04:02
>>409
このスレに張られているURLは参考になるものが多いと思う。
http://pc8.2ch.net/test/read.cgi/tech/1142667446/l50
413デフォルトの名無しさん:2006/03/28(火) 17:48:10
>>412
ほんとだ、参考になる。じっくり読んでみるよ。
414デフォルトの名無しさん:2006/03/28(火) 18:40:50
あれ?
また例外処理のスレが立ったのか。
415Defaultの名無しさん :2006/03/28(火) 21:45:51

ちょっと変わったfunctorが作りたいです。

普通はresult operator(arg1,arg2, ...)といった感じで実行ですが、
すべての関数は,void Execute()で実行します。

このとき引数の値を事前にfunctorに保持させるようにします。
戻り値もExecute()実行後にfunctorに保持し、適宜,rerult GetResult()みたいな感じで取り出すとします。

ここで問題となるのが、引数argN型や戻り値result型の保持の問題です。
argやresultが参照の場合はやっかいです。メタプログラムして値型にすれば容易に解決できると思いますが、
Execute()実行まえに参照先が変化している場合(マルチスレッドが理由とかで)もあるので、
やっぱり参照で保持したい・・・ポリモルフィズムしてほしい・・・

なにか良い知恵をご教示願います。
416デフォルトの名無しさん:2006/03/28(火) 21:50:34
ポインタで持てよ
417Defaultの名無しさん:2006/03/28(火) 22:10:27
どうもありがとうございます。

でも、
保持している関数ポインタ(func_ptr)の引数がarg&だった場合はarg*で保持するとします。
このとき、Execute()実行時はfunc_ptr(*arg)が起動するわけですが、
argが抽象クラスの場合はコンパイルされません・・・
418デフォルトの名無しさん:2006/03/28(火) 22:49:57
コンパイルされません、って何だよ。
cc1:error:sorry unmplemented.か?
419デフォルトの名無しさん:2006/03/28(火) 22:55:06
#include <stdio.h>
struct IHoge{ virtual void hoge()= 0;};
struct CHoge : IHoge{ void hoge(){printf("h\n");} };
int f(IHoge &i){ i.hoge(); return 0;}
struct ce { IHoge *arg; int ret; int (*func)( IHoge & );
void Execute(){ ret = func( *arg ); }
};
int main(){
CHoge ch;
ce e; e.arg =&ch; e.func = f;
e.Execute();
printf("%d\n", e.ret );
}
こういうことだろ。
420デフォルトの名無しさん:2006/03/28(火) 23:10:16
普通にコマンドパターンだよね
421デフォルトの名無しさん:2006/03/29(水) 00:58:59
メソッドと関数の違いってなんですか?
ほとんど同じとは聞くけど正確な違いとか定義とかあるんでしょうか?
422Defaultの名無しさん:2006/03/29(水) 01:00:01
415です。みなさんありがとう!
自宅に帰ってきました。
とりあえず、こんな感じで使えればなあと思ってます・・・
class FunctorBase{
public: virtual void Execute(const long& arg)=0;
...};
template<typename Result,template Argument> class Functor
{
public:
typedef typename FuncPtrCreate<Result,Argument>::FuncPtr FuncPtr;//関数ポインタの型
typedef typename FuncPtrCreate<Result,Argument>::ResultType ResultType;
typedef typename FuncPtrCreate<Result,Argument>::Argtype Argtype;
private:
typedef typename FuncPtrCreate<Result,Argument>::ResultHolder ResultHolder;
typedef typename FuncPtrCreate<Result,Argument>::ArgHolder ArgHolder;
public:
explicit Functor(FuncPtr func) : FuncPtr_(func) { }
virtual void Execute() { ResultHolder_.Set( FuncPtr(ArgHolder_.Get()) ); }
void SetArg(Argtype arg) { ArgHolder_.Set(arg); }
ResultType GetResult() { return ResultHolder_.Get() }
private:
FuncPtr FuncPtr_;
ResultHolder ResultHolder_;
ArgHolder ArgHolder_;
...
};
つづく
423Defaultの名無しさん:2006/03/29(水) 01:01:29
つづき
使い方は・・・

Strung Func(long& arg);

int main()
{
Functor<String,long& arg> functor(&Func);
functor.SetArg(10);
functor.Execute();
Functor<String,int&>::ResultType rerult=temp1.GetResult();
} とりあえず寝ます。
424デフォルトの名無しさん:2006/03/29(水) 01:03:57
425Defaultの名無しさん:2006/03/29(水) 01:04:05
あっまちがい
最下段temp1.GetResult(); はfunctor.GetResult();
めんご
426デフォルトの名無しさん:2006/03/29(水) 01:11:47
>>422-423
せめてコンパイルできるかどうかぐらいチェックしてから貼れよ。
使われてない FunctorBase とか宣言されてない FuncPtrCreate とかボロボロだぞ。
427デフォルトの名無しさん:2006/03/29(水) 05:44:28
__DATE__ および __TIME__ の文字列のフォーマットって、
処理系依存ですか?それとも規格で厳密に決まっていますか?
428デフォルトの名無しさん:2006/03/29(水) 07:37:51
16.8 Predefined macro names
The following macro names shall be defined by the implementation:
...
_ _DATE_ _ The date of translation of the source file (a character string literal of the form
"Mmm dd yyyy", where the names of the months are the same as those generated by the asctime
function, and the first character of dd is a space character if the value is less than 10). If the date of
translation is not available, an implementationdefined valid date is supplied.
_ _TIME_ _ The time of translation of the source file (a character string literal of the form "hh:mm:ss"
as in the time generated by the asctime function). If the time of translation is not available, an
implementationdefined valid time is supplied.
429デフォルトの名無しさん:2006/03/29(水) 07:43:50
6.10.8 あらかじめ定義されたマクロ名 次に掲げる七つのマクロ名は,
処理系によって定義されていなければならない。
_DATE__
前処理翻訳単位の翻訳の日付("Mmm dd yyyy"の形式をもつ単純文
字列リテラルで, 月の名前はasctime関数で生成されるものと同じ
とする。dの値が10より小さいときは, その最初の文字は空白とす
る。)。翻訳の日付が得られない場合, 処理系定義の正しい日付を提供
しなければならない。
(略)
430デフォルトの名無しさん:2006/03/29(水) 08:46:10
>>421
メソッドはJava/C#などの言葉。
C++ではメンバ関数。
431デフォルトの名無しさん:2006/03/29(水) 12:22:15
_DATE__
とか使ってログを取ろうと思ってログ関数作ったけど
その関数の中で呼んでも意味無いんだね。当たり前だけど。
使えないと思った。
bindとか使ったら使いやすくなるだろか。
432デフォルトの名無しさん:2006/03/29(水) 12:30:33
>>431 bind ってなんですか?
433デフォルトの名無しさん:2006/03/29(水) 12:41:45
VC++6では、もしかしてstdのalgorithmって使えないんですかね?
434デフォルトの名無しさん:2006/03/29(水) 12:44:40
>>433
使えるよ。 STLport 使うとだいぶマシになるよ。
435デフォルトの名無しさん:2006/03/29(水) 12:50:39
.netでは普通に動くんですが、
vc6だとmaxは定義されていないとでるんですが
#include<algorithm>
#include<iostream>

using namespace std;

void main(){
int a,b,c;
a = 0;
b = 1;
c = max(a,b);
cout << c << endl;
cout << a << b << endl;
}
436デフォルトの名無しさん:2006/03/29(水) 13:26:04
>>435
エラーメッセージはコピペが基本。
437デフォルトの名無しさん:2006/03/29(水) 13:53:47
.netでは普通に動くんですが、
vc6だとmaxは定義されていないとでるんですが

#include<algorithm>
#include<iostream>

using namespace std;

void main(){
int a,b,c;
a = 0;
b = 1;
c = max(a,b);
cout << c << endl;
cout << a << b << endl;
}

error C2065: 'max' : 定義されていない識別子です。
438デフォルトの名無しさん:2006/03/29(水) 14:04:43
過去ログ読んだか?
同じ質問があった気がする
439デフォルトの名無しさん:2006/03/29(水) 14:18:28
過去ログ多すぎて読めませんwww
440デフォルトの名無しさん:2006/03/29(水) 14:48:53
b馬鹿だな、ここで質問してググりながらここを見て放置しとくんだよ
441デフォルトの名無しさん:2006/03/29(水) 15:10:22
そうしてますね。
ていうか、
「過去ログ呼んだか?」の一行をぜひ、
「できないよ」「できるよ」の答えの一行にしてほしい質問者です
442デフォルトの名無しさん:2006/03/29(水) 15:34:43
>>437は質問の体をなしていないから答えようがないんだが。
std::maxが使えるか、という質問ならたぶん「使えない」でいい。
algorithmの各関数が使えるか、という質問なら、「使えるものもある」で。
443デフォルトの名無しさん:2006/03/29(水) 16:00:17
「使えるものもある」ですか。
ありがとうございます。
444デフォルトの名無しさん:2006/03/29(水) 17:17:03
w
445デフォルトの名無しさん:2006/03/29(水) 17:53:29
過去ログ読んだか?1〜47まであるぞ、気合い入れて読め。
446デフォルトの名無しさん:2006/03/29(水) 18:05:41
過去ログにgrepかければ一瞬です。
447デフォルトの名無しさん:2006/03/29(水) 18:40:27
犬糞環境なんて整えられません><
448デフォルトの名無しさん:2006/03/29(水) 18:50:53
>>430
>C++ではメンバ関数。

非公開メンバ関数をメソッドとは呼ばないと思う。
449デフォルトの名無しさん:2006/03/30(木) 00:17:53
過去ログが落ちてしまって残ってない場合はどうやれば…
450デフォルトの名無しさん:2006/03/30(木) 01:01:49
>>449
●を買う。鯖代への貢献にもなって一石二鳥。
それでも拾いきれないものについては、保存している人を探して、拝み倒して
どこかにうpしてもらう。その後、君がまとめサイトを作れば完璧だ。
451デフォルトの名無しさん:2006/03/30(木) 01:31:10
にく
452デフォルトの名無しさん:2006/03/30(木) 01:37:34
453デフォルトの名無しさん:2006/03/30(木) 09:37:06
C++初心者の者ですが、
http://www.asahi-net.or.jp/~yf8k-kbys/newcpp17.html
を見ながら勉強していたら、最後のwhile文からを
while(1){
int ans;

cout << "1 鳴かす 2 年収を表示 3 昇給 4 やめる"<<endl;
cin >> ans;
if(ans == 1)
dora.naku();
else if(ans == 2)
cout<<dora.get_nensyu();
else break;
}

}

こう書くと年収の表示がおかしくなります。
自分で色々書き方を変えても原因がどうにも分かりません。
どなたか何処がダメなのか教えてください。
454デフォルトの名無しさん:2006/03/30(木) 09:47:59
>>453
endl が抜けてるせいで改行が入らない上にでバッファリングされてるんじゃね?

そうじゃないなら、「おかしくなる」って言われてもわかんねーよ。
ちゃんと症状書け。
455デフォルトの名無しさん:2006/03/30(木) 10:05:22
C++はじめたばっかりの初心者なんですが

//hello3.cpp
#include <iostream>
#include <string>
using namespace std;

int main()
{
string name;
int tosi;

cout << "こんにちは。私はコンピュータです。" << endl;
cout << "あなたの名前を入力してください。" << endl;
cin >> name;

cout << name "さん。よろしく。" << endl;

cout << "ところで、" << name << "さん。失礼ですがお年はいくつですか?" <<endl;
cout << "(入力は必ず、半角の数字でお願いします。)" << endl;
cin >> tosi;

cout << "なるほど。" << tosi << "歳ですか。" << endl;
cout << "私はもうすぐ2歳のマシンです。"<<endl;
}

この例文を実行すると
エラー E2379 hello3.cpp 15: ステートメントにセミコロン(;)がない(関数 main() )
とか出ます・・・
セミコロンちゃんとつけてるんですが・・・・どこが悪いのかわかりません、教えてください。
456デフォルトの名無しさん:2006/03/30(木) 10:14:29
>>455
× cout << name "さん。よろしく。" << endl;
○ cout << name << "さん。よろしく。" << endl;

つか、エラーが出たら、その箇所を見て間違いを探す練習をした方がいいと思うぞ。
457デフォルトの名無しさん:2006/03/30(木) 10:17:02
コンパイラのエラーメッセージはエラーを起こした行番号の参考程度にし、
エラーメッセージの内容は無視して、まず該当行から自力で間違いを探す方がいいな
458デフォルトの名無しさん:2006/03/30(木) 10:31:17
うっひょう!できました!
>>456-457
ありがとうございました!いままで○○Pとかにいたんでここの優しさがしみる・・・・
459デフォルトの名無しさん:2006/03/30(木) 10:31:38
>>457
いや、内容を無視するのはまずい。先に内容を考えた後で、
原因と直結しないメッセージである可能性も考慮するのが正解だろう。
慣れてくればそういうメッセージは見分けられるようになる。
460453:2006/03/30(木) 10:43:00
>>454
おかしくなるというのは、関数から返ってくる年収の値が100のはずなのに
実行すると1401とか表示されるということです。

>endl が抜けてるせいで改行が入らない上にでバッファリングされてるんじゃね?
これってどういうことでしょうか?
確かにdora.get_nensyu()<<endl;と直すとちゃんとした値が表示されるのですが
改行がないと何がまずいのでしょうか。
461デフォルトの名無しさん:2006/03/30(木) 10:58:20
>>460
endl ぐらい Google でも使って自分で調べろ。
あと標準出力のバッファリングもな。

で、 endl 入れると「ちゃんとした値」ってことで 100 と表示されるのか?
「1401とか」って何だよ?実行するごとに変わるのか?
改行が無いのがまずいと思わないならそれはお前の勝手だ。気にするな。

書き込む前によく読みなおして、自分以外の人が読んでも
理解できるかどうか確認してください。
462デフォルトの名無しさん:2006/03/30(木) 10:59:27
>>460
改行を入れるまで、文字列を出力しないでバッファにためこむ環境があるってことさ。
つまり、std::endl(もしくは'\n')を入れないと文字列が出力されないことがあるので、必ず入れましょう、ということ。
463デフォルトの名無しさん:2006/03/30(木) 11:03:53
>>462
'\n' をいれてもバッファのフラッシュはかからない。
「必ず入れましょう」ということで汎用のコードに endl ばら撒かれてもフラッシュしまくりで困る。

きちんと使い分けましょう。
464デフォルトの名無しさん:2006/03/30(木) 11:08:27
フラッシュしたかったらstd::flushマニピュレータ突っ込めばOK
465453:2006/03/30(木) 11:20:21
>>461-462
ありがとうございます。おかげでやっと意味が分かりました。
この手のエラーは初めてで何が原因だったか全く分からなかったため
言葉足らずな質問になってしまいすいませんでした。
466デフォルトの名無しさん:2006/03/30(木) 11:49:10
>>455
× cout << name "さん。よろしく。" << endl;
○ cout << name << "さん。よろしく。" << endl;
467デフォルトの名無しさん:2006/03/30(木) 11:52:45
468デフォルトの名無しさん:2006/03/30(木) 11:54:54
>>448
非公開だろうと何だろうと、メンバ関数をメソッドと呼ぶのは誤り。
469デフォルトの名無しさん:2006/03/30(木) 12:00:09
メンバ関数という用語も標準規格で定義されているのですか?
470466:2006/03/30(木) 12:06:11
>>467
orz
471デフォルトの名無しさん:2006/03/30(木) 12:07:47
>>466-467
すいません、ありがとうございます。
472デフォルトの名無しさん:2006/03/30(木) 12:25:58
だれかが言う前に俺が言ってやる



473デフォルトの名無しさん:2006/03/30(木) 13:21:40
>>472
あ、言おうと思ったら既に言われてたw
474デフォルトの名無しさん:2006/03/30(木) 15:19:58
>>469
つ[JIS X3014]
つ[google]
つ[自助努力]
475デフォルトの名無しさん:2006/03/30(木) 15:35:26
>>469
Functions declared in the definition of a class, excluding those declared with a friend specifier,
are called member functions of that class.
476デフォルトの名無しさん:2006/03/30(木) 19:27:08
感情クラスから怒りクラスを派生させて、怒りクラスから憎しみクラスを派生させて…
ってやっていったら人工知能つくれませんか?
477デフォルトの名無しさん:2006/03/30(木) 20:09:00
478476:2006/03/30(木) 23:00:16
僕は馬鹿にされて軽くあしらわれたのですか?
479デフォルトの名無しさん:2006/03/30(木) 23:37:56
MFCてなによ?
C++の書き方覚えても
あまり意味ないわけ?

裏切られた気分・・・・
480デフォルトの名無しさん:2006/03/30(木) 23:53:25
>>479
MFCはWindows アプリケーションを作るためのフレームワーク。
Winアプリを作るのが少しは楽になるかもしれない。ただ最近は下火。

C++の高度なことはあまり要求されないので、
MFCを使いたいがためにC++を学んだのであれば、
たしかに裏切られた気分になるかもしれない。
481デフォルトの名無しさん:2006/03/31(金) 09:56:08
お前ら、Windows で開発するとき、
各種ライブラリってどこに置いてますか?
C:\ に置いてます?たとえば C:\boost\lib\ みたいに。
その辺、Windows ってコンセンサスって無いですよね?

ルートに全部置くのもなんか汚い(?)気がするし、
かといって C:\Document and Settings\以下略
みたいな長ったらしい、かつ、空白を含むパスに置くのも嫌だしなぁ。
Vista では長ったらしいパスをやめた、って話だけど。
482デフォルトの名無しさん:2006/03/31(金) 10:02:25
Windows Vistaにはシンボリックリンクがいっぱい
http://eside.homeip.net/columns/winvista_fs.html
483デフォルトの名無しさん:2006/03/31(金) 11:43:13
>>481

普通は、libpathにパス指定して好きなとこに置くだろ。
パス指定されると、コンパイルが遅いとか言っていた時代と違うんだから。
484デフォルトの名無しさん:2006/03/31(金) 12:39:44
長ったらしくて空白を含むパスにLib置いて挙動がおかしくなるコンパイラは
Win32対応って言わないと思うんだけどなぁ。
485デフォルトの名無しさん:2006/03/31(金) 12:43:32
スレ違いだが、 make のリスト区切りがスペースなのが困る。
486デフォルトの名無しさん:2006/03/31(金) 12:45:08
>>481
/usr/lib の下にまとめてラクになっちゃえばOK。
Document and Setting も Vista では /user/ だし。
487デフォルトの名無しさん:2006/03/31(金) 12:45:08
>>483
やっぱそんなものなのか
おいらは普段はLinuxでやってるんだけど
ときどき頼まれてWinで開発するときに
どこに置いたらいいものか悩む
488487:2006/03/31(金) 12:50:35
ちなみにUNIXの場合も決め打ちされてる訳ではない
489デフォルトの名無しさん:2006/03/31(金) 12:57:58
>>485
GNU makeだと\でエスケープできるよ
490デフォルトの名無しさん:2006/03/31(金) 20:17:34
eclipse/cdt 以外でリファクタイングできるツールないのかな?

javaぽい書き方してjavaのリファクタイングツールを流用するしかない?
491デフォルトの名無しさん:2006/03/31(金) 21:47:18
>>487
適当にどっかにライブラリ用のフォルダ作ってまとめとくのが普通でしょ

こんなの、落としてきたインストーラ無しのソフトを
どこに解凍して置いておこうかな、っていうレベルの問題だと思う

linuxでもそういうことあるし同じでしょ・・・
全体的なフォルダ構成が違うけど
492デフォルトの名無しさん:2006/03/31(金) 22:58:05
最近話題のstatic_castってなんだよ
エロイのか?
493デフォルトの名無しさん:2006/03/31(金) 22:59:02
エロくはないけど、大流行だよ!
ナウなヤングにバカウケ
494デフォルトの名無しさん:2006/03/31(金) 23:00:48
バカウケの部分をもっと
ナウでヤングに出来ないかな?
495デフォルトの名無しさん:2006/03/31(金) 23:01:57
>>491
適当に置くこともできるけどUNIXではコンセンサスみなたいなものはあるよ
手元に環境あれば
$ man hier
してみれば解説されている
496デフォルトの名無しさん:2006/03/31(金) 23:47:13
497デフォルトの名無しさん:2006/03/32(土) 03:07:42
>>489
関数に渡したときもうまくいく方法があれば教えてほしい。(あっちのスレでね)
http://pc8.2ch.net/test/read.cgi/tech/1029599472/358-360
498デフォルトの名無しさん:2006/04/02(日) 00:02:47
static_castと普通の(char*)みたいなキャストって何が変わるの?
499デフォルトの名無しさん:2006/04/02(日) 00:09:54
>>498
static_cast のほうができることが少ない。そのぶん安全。
また、検索しやすいという効果もある。
500デフォルトの名無しさん:2006/04/02(日) 00:21:14
従来のキャストはできることが多すぎたから,
static_cast と const_cast と reinterpret_cast に分割した,
と思っておけば大体おk.

static_cast: 暗黙にできる型変換を明示的にやるために使う.
const_cast: const/volatile をつけたりはずしたりするために使う.
reinterpret_cast: 実装に依存するような型変更のために使う.
501デフォルトの名無しさん:2006/04/02(日) 00:30:45
>>500
誤解してるやつが多いんだが、 const, volatile をつけるときは const_cast 使わなくていい。
危険なキャストを洗い出すときに const_cast 検索するから、つけるときは static_cast で。
502デフォルトの名無しさん:2006/04/02(日) 00:47:56
>>501
すまん、意味がわからん。
C style のキャストも const_cast も使用せずに
どうやって const, volatile を付けるん?
暗黙の変換のこと?
503デフォルトの名無しさん:2006/04/02(日) 00:48:41
>>502 「つけるときは static_cast で」
504デフォルトの名無しさん:2006/04/02(日) 01:06:33
void*からint*等へのキャストはstatic?reinterpret?
いつもはreinterpretを使ってたんだけど
あちこちでstaticの方でやってるのを見かけて自信がなくなってきてる
505デフォルトの名無しさん:2006/04/02(日) 01:08:08
>>503
ああ、すまん。そーゆー意味か。
506デフォルトの名無しさん:2006/04/02(日) 01:18:07
>>504
void* からオブジェクトポインタへの変換は static_cast 。
reinterpret_cast は間違い。
507デフォルトの名無しさん:2006/04/02(日) 01:32:10
reinterpret使うくらいならCスタイルかなぁとか思ったりする。
検索はしづらくなるけど
508デフォルトの名無しさん:2006/04/02(日) 01:32:55
reinterpret_castはbit表現のレベルで、無理やり変換する場合だけって考えていいのかな
509デフォルトの名無しさん:2006/04/02(日) 01:36:59
>>508
ビット表現が保持されると決まっているわけじゃない。
510504:2006/04/02(日) 01:41:22
>>506
thanks

staticは安全なの、reinterpretは危険なのを強引に、
dynamicはvtable付きクラスをダウンキャスト、constはconst,volatile外し
ってイメージで使ってた。
無チェックなダウンキャストとか、継承関係に無いポインタ間のキャストは
危険そうだったからreinterpretのイメージだったけど
危険さ具合がイメージとちょっとずれてたみたい。
511デフォルトの名無しさん:2006/04/02(日) 01:41:34
>>509
む、そうなのか・・・
ちょっと適当に自分でいろいろ試すことにする
512デフォルトの名無しさん:2006/04/02(日) 01:48:42
>>510
無チェックなダウンキャストは static_cast 。
継承関係が無ければエラーになる。
reinterpret_cast だとエラーにならない。
513デフォルトの名無しさん:2006/04/02(日) 02:05:07
コンパイラの実装依存のがreinterpretで
特殊用途のdynamic,constの他は全部staticすか
514デフォルトの名無しさん:2006/04/02(日) 02:23:51
プリミティブ型のポインタ変換はstatic_castでよかったのか。

どうもいまいちreinterpret_castの使いどころがわからないんだよな。
515デフォルトの名無しさん:2006/04/02(日) 02:25:23
int i をストリームにバイナリ出力するとき、
out.write(reinterpret_cast<char*>(&i), sizeof(i));
してるんだけど、これって実装依存になるのかな?

規格中に
・ int* から void* に変換したとき、変数の記憶域の先頭を指す。
・ void* と char* は同じ内部表現を持っている。
っていうのは見つけた。
だから static_cast<char*>(static_cast<void*>(&i)) なら大丈夫そうなんだけど、
これは激しくウザイ。
516デフォルトの名無しさん:2006/04/02(日) 02:32:56
構造体をfstreamのread,writeで書き込むときって、char*にキャストするよね。
この場合はreinterpret_castでいいのかな。
517デフォルトの名無しさん:2006/04/02(日) 02:38:03
>>516
普通、絶対そんなことしないと思うが、 alignとか考えたことある?
518デフォルトの名無しさん:2006/04/02(日) 02:44:20
結論
皆キャストも満足に扱えてない。
519デフォルトの名無しさん:2006/04/02(日) 02:48:50
struct Data {
int i;
char c;
} d;
write(fp, &d, sizeof(Data));
520デフォルトの名無しさん:2006/04/02(日) 02:54:56
>>517
read, write の引数は char* なわけだが、「普通」はどうするのかね?
521デフォルトの名無しさん:2006/04/02(日) 02:56:11
>>520
void*じゃねーの
522デフォルトの名無しさん:2006/04/02(日) 03:02:16
>>521
POSIX の read, write は void* だな。
でも今話してるのは iostream の read, write で、こっちは char* になってる。
523デフォルトの名無しさん:2006/04/02(日) 03:06:02
あるクラスのインスタンスへのポインタをlistに入れた場合、
そのlistをdeleteすればそのクラスの実態まで消えるのでしょうか?
524デフォルトの名無しさん:2006/04/02(日) 03:07:47
>>523 消えない。
525デフォルトの名無しさん:2006/04/02(日) 03:14:56
>>524
別途削除ですか……
526デフォルトの名無しさん:2006/04/02(日) 03:16:29
>>525
Effective STLとかにそのへんのこと詳しく載ってる
527デフォルトの名無しさん:2006/04/02(日) 03:24:49
>>525
即レス乙です。ちょっと憂鬱読んで気になったもので……
528デフォルトの名無しさん:2006/04/02(日) 03:26:40
自分にレスしてどうする!
>>526でした。
529デフォルトの名無しさん:2006/04/02(日) 08:02:38
static_castでコンパイラに怒られたらそれっぽいcastに書き換えてるようじゃダメなのか…
530デフォルトの名無しさん:2006/04/02(日) 08:03:34
>>529
なんのためにキャストしようとしているか理解していればそんなことはおき得ない
531デフォルトの名無しさん:2006/04/02(日) 08:08:38
>>525
その他に、ポインタが指す先がすべて new で確保したもので、2カ所以上からポイントされていないという保証も必要
ポインタの列を list で扱うというパターン自体が、そもそも自動 delete を望まないか、list で作っているのが部分集合で
全体集合を作っているコンテナに破壊の仕掛けがあるような場合に使うもの
532デフォルトの名無しさん:2006/04/02(日) 08:11:23
素直にポインタでなくオブジェクトそのものを突っ込めばよくね?
533デフォルトの名無しさん:2006/04/02(日) 08:16:51
>>531
そんなときこそ delete して 0 代入イディオムですよ
534デフォルトの名無しさん:2006/04/02(日) 09:40:43
っ[boost::shared_ptr]
535デフォルトの名無しさん:2006/04/02(日) 09:48:01
>>517
alignは#pragmaでごにょごにょしました。
やっぱり変数ごとに一個ずつ読んだり書いたりしないとだめなんかな。
ファイルヘッダとかは一気に構造体で扱っちゃったほうが分かりやすいと思ったんだけど……。
536デフォルトの名無しさん:2006/04/02(日) 09:57:57
基本型しか使ってない構造体ならwrite(&struct)でいいとおもうけど。
互換性をいいだせば整数とかも文字列に変換せんといかんのじゃないか。
537デフォルトの名無しさん:2006/04/02(日) 11:29:33
えーっと、例えば、#pragmaかなんかでalignを1バイト境界に揃えた構造体、
struct A{
unsigned int data;
} a;

ifstream.read((char*)&a, sizeof(a));
したときの互換性?で致命的な問題って何があるでしょうか。
エンディアンぐらいしか思い浮かばない自分は半年ROMるべきでしょうか。
538デフォルトの名無しさん:2006/04/02(日) 14:15:52
intのサイズとか。
539デフォルトの名無しさん:2006/04/02(日) 14:20:59
>>537
思いつくのは揚げ足取り:
・alignmentを1バイト境界にできないコンパイラが存在したときに困る
・メンバにポインタや参照を含むときに望ましい結果にならない(そもそもやろうとしてないだろうけど)
・バイナリでの入出力は、どうも、C++では熟考されてない雰囲気
・アドバイス「構造体よりクラスを使え」

漏れも、たとえばWindowsBMP(DIB)のBITMAPINFOHEADERのような場合、
#pragma等でごにょってread(&struct)してるよ。ついでにoperator>>()も定義して
BITMAPFILEHEADER bf;
cin >> bf;
540539:2006/04/02(日) 14:40:13
> C++では熟考されてない雰囲気

これの意味は、バイナリ入出力では「型のビット表現」そのままを入出力するしかできないので、
型の大きさ(char単位の大きさ)、エンディアン、浮動小数点なら各ビットの意味など
判別・読み書き時にC++ライブラリの支援がない(支援ができない)。

そもそも、読み書きすべきバイナリデータが、C++だけで使われるとは限らない。
アマゴサ星系のエル・オーリアン人が、彼らの特殊言語で読み書きするかもしれない。

バイナリで扱うなら、ファイルの先頭あたりにUTFのBOMのようなものを入れるしかない。
「安全」さを求めるならテキスト入出力を使うべきなんだろう。

非現実的だが。

>>538
その問題は、read((char*)&a, sizeof(a))の問題ではなく、バイナリ入出力自体の問題じゃないかな。
541デフォルトの名無しさん:2006/04/02(日) 14:49:56
gimpのbmpヘッダ書き込みのところのソースとか見てみたら
構造体のメンバを一つずつファイルに書き込んでたから
アラインメントとか考えるとこういう風になっちゃうのかなー
と思って、おれもそうしてた

まあ、C言語だけど
542デフォルトの名無しさん:2006/04/02(日) 14:59:04
>>538-539
・実際はtypedefしたdwordなので、intのサイズが違ったらtypedefを書き換えればいいかなぁとか。
・1バイト境界に出来ないコンパイラは考えてませんでした。反省。
・ポインタを含むようなら当然このような手段は取らないです。
・C++ではストリーム使うべきかなと思ったんですが……やめたほうがいいですかね。
・単にデータをバインドするだけの使い方をしたかったので、純粋な構造体を使いました。
 構造体はこういう使い方をするべきではないでしょうか。
 実際はファイルを扱うクラスのreadメンバ関数の中で処理してます。
 virtualメンバ関数があるとsizeofがずれてしまうので構造体なんですけども。
>BITMAPINFOHEADER
 はい、まさにそんな感じです。

ifstream.readを変数分全部書くと、構造体メンバの変更があったときコードにも影響が出ますよね。
もっといい書き方あるんでしょうか。
543デフォルトの名無しさん:2006/04/02(日) 15:03:10
ファイルフォーマットとかプロトコルっていうものをちゃんと
考えれば、ほぼ必然的に int とか struct をそのまま write
したりは出来なくなるよね。

定義されてる(or 定義した) とおりのデータを、定義どおりの順に
定義どおりのサイズで読み書きする。たまたまパディングを調整
できるコンパイラで、バイトオーダーもあっていれば struct とかも使える。
そんだけのこと。
544542:2006/04/02(日) 15:08:52
長々と書いてたらその間にレスが……
>>540
可搬性を求めると問題は尽きないんですね……。
>>541
やっぱりそうなっちゃいますか〜。
>>543
なるほど……良くわかりました。
変数を全部読み込む手間 <-> 一度に読み込むリスク
でトレードオフってことですね。
545デフォルトの名無しさん:2006/04/02(日) 15:27:22
プラットフォーム固定なら align してベタ書きでいいと思うけどね。
GUI ならどうせ他の色んな所でプラットフォーム固定のコードを書かざるを得ないだろうし、
ファイルの読み書きのところだけ可搬性を重視してもナンセンスかと。
546542:2006/04/02(日) 15:34:45
GUI部分は別にして、コアだけ作っていたので、
ある程度汎用性があったほうがよいかと思って色々と考えていました。
でも確かにここだけ可搬性を求めても仕方ないですね。
align指定と構造体で置いておくことにします。
色々とどうもありがとうございました。
547デフォルトの名無しさん:2006/04/02(日) 18:35:19
C++ なら、読み書きを構造体のメンバ関数として提供しておけば、
プラットフォームを変更したところで、
その構造体のところの定義をいじっただけで済むと思われ。
548デフォルトの名無しさん:2006/04/02(日) 21:00:28
個人的にはメンバ関数を持った構造体にalignmentを指定したくないんですけど、杞憂でしょうか。
何か気持悪いんですが……。
549デフォルトの名無しさん:2006/04/02(日) 21:12:14
>>548
個人的には彼女を持ったからオナニーをしたくないんですけど、杞憂でしょうか。
何か気持悪いんですが……。


と言われてる気分だ。お前の勝手にしろ。
550デフォルトの名無しさん:2006/04/02(日) 21:37:05
ちょっと前からバイナリ出入力と関連してアライメントの話が出てくるが、関係がわからん。
普通に sizeof 使ってたらアライメントも問題にならないと思うんだけど。
551デフォルトの名無しさん:2006/04/02(日) 21:39:07
>>550
別環境では、ずれる可能性があるって話では?
552デフォルトの名無しさん:2006/04/02(日) 21:48:24
>>551
別環境だったらサイズやビット表現も違う可能性もあるだろ。
アライメントだけ指定する意味が無い。
553デフォルトの名無しさん:2006/04/02(日) 22:14:21
>>548
仮想関数さえなければ大丈夫だろ。
554デフォルトの名無しさん:2006/04/02(日) 22:15:30
>>552
そんなもん織り込み済みで話してる
555デフォルトの名無しさん:2006/04/02(日) 22:15:48
>>553
仮想関数があってもなくても関係ない。「好きにしろ」で終わり。
556デフォルトの名無しさん:2006/04/02(日) 22:19:38
お好きなまでに…
557デフォルトの名無しさん:2006/04/02(日) 22:19:58
>>555
仮想関数テーブルへのアドレスが読み書きされちゃうじゃん。
558デフォルトの名無しさん:2006/04/02(日) 22:23:31
>>557 それとアライメント指定の是非に何の関係が?
559デフォルトの名無しさん:2006/04/02(日) 22:28:29
>>554
じゃぁ >>550 の答えは?
560デフォルトの名無しさん:2006/04/02(日) 22:39:25
>>559
 漏れ個人的にはグローバルなコンパイルオプションなんかで
(ファイル書き出しなどに使う)構造体のレイアウトが変わったら
イヤだから、#pragma pack とかでアライメントは指定してる。

関連プログラム全部同じオプションでコンパイルするしー、とか
未来永劫アライメントなんか変えないしー、
っていう人なら確かにいらんかもしれないな。
561デフォルトの名無しさん:2006/04/02(日) 23:00:29
VCとx86系を使ってますが、
コンパイラが勝手にintとかshortをワード、ダブルワード境界に揃えてしまいました。
それでは構造体で一気に読み込むとパディングのせいで実際のファイル構造とずれてしまうので、
#pragmaでアライメントをバイト境界に指定するわけですが、
#pragmaの機能は当然処理系依存機能なので余り広範囲に使いたくありません。
(コンパイラを変更したら#pragmaを恐らく変更しなければならない)
エンディアンはこの際おいておいても、同一の性質を持つ記述を散在させるのは気持ちが悪いので、
PODのみを持つ構造体にアライメントを指定しておいて、それを扱うクラスにはアライメントを干渉させないように
したのです。
562デフォルトの名無しさん:2006/04/02(日) 23:07:28
>>560
なんか感覚おかしくね?
将来的なことを心配するならアライメント依存しない方法を選ぶだろ。
563デフォルトの名無しさん:2006/04/02(日) 23:10:23
「構造体を一気に読む」自体が処理系依存なわけで。
564デフォルトの名無しさん:2006/04/02(日) 23:36:39
メモリダンプ・ロードなんてどう考えたってハックじゃん。
そんなの使う場所で環境依存云々言ったって五十歩百歩。
565デフォルトの名無しさん:2006/04/02(日) 23:44:09
>>勝手にしろ、好きにしろ
皆さんのお考えを聞いてみたかったのです……。

>>558
仮想関数を持ったクラスはsizeofの値が増加します(VCでは増えました、処理系によるかもしれません)。
この場合alignmentではなくこの増加分がどこに収められるかが心配なのです。
sizeofでサイズをとっての読み書きを想定しているので、
sizeofがずれるとread(&struct, sizeofA)では問題があるのです。

>>562
プログラムがalignmentに依存しないとしても、ファイルフォーマットは固定されてます。
構造体で一気に読むとしたらalignmentは少なからず関与してくると思います。

>>563
処理系依存なのはalignとエンディアンとパディングの大きさだけかと思っていました。
構造体一気読み自体が処理系依存とはどういうことでしょうか。
fstreamの仕様に関わることでしょうか。

>>564
ハックになってしまいますか。
メモリダンプというよりバイナリファイルダンプに近いんですけど。

なんだか収まりがつかなくなってきてしまったので、最後に皆様に率直にお聞きします。
私の構造体一気読みのコードを保守する羽目になったら私を殺そうと思いますか?
566デフォルトの名無しさん:2006/04/02(日) 23:47:25
>>519がまともに使えると思ってるやつばっかり、ってことだろ?
567デフォルトの名無しさん:2006/04/02(日) 23:48:42
構造体のメンバのメモリ上での順番はC++では規定されてたっけ?
あとchar以外の変数のサイズは処理系依存だけど。
568デフォルトの名無しさん:2006/04/02(日) 23:52:25
alignとエンディアンとパディングが処理系依存なわけだから、
それを前提にしている構造体一気読みも当然処理系依存だろ。

>565
Win32上の処理系だと、COMの関係で、vtblはクラスの先頭に
もってきてる可能性が高い。
569デフォルトの名無しさん:2006/04/03(月) 00:04:13
厳しい現実を言うと char のビット数すらも固定ではなかったり
570デフォルトの名無しさん:2006/04/03(月) 00:11:49
だが、unsigned char の最大値が255以上
sizeof(char)==1
であることは規定されている
571542:2006/04/03(月) 00:28:49
>>567
共用体ではないクラスの非静的データメンバがアクセス指定子が間に入らずに宣言された場合、
後で宣言されたデータメンバのほうがクラスオブジェクト内でより高位のアドレスになるように割り当てられる。
(X3014:2003より引用)
らしいです。
型のサイズについては>>542の最初の項のとおりです。

>>568
そうですね……。
3つの条件をクリアしたらいいのだろうか、と思いましたが、
よく考えるとつまりそれが処理系依存でした。

処理系依存でOKなら一気でもOK
ダメなら一個ずつ読み書きしなさい、ということですね。
572デフォルトの名無しさん:2006/04/03(月) 00:35:10
>>565
結局「勝手にしろ、好きにしろ」としかいえないのが現実なんじゃないの?

構造体一気読みはコードを書くのが簡単だし、パフォーマンス上好ましいことも
あるだろう(fstreamを使っている時点でアレかもしれんが)。

他プラットフォームへの移植性が求められるなら、一バイトずつ読み書きするのが
比較的良い方法になるだろう。それでもC++の規格はすべての環境で同じファイル
フォーマットが使えることを保証してはくれないだろうけど。

その気があれば、移植するすべてのプラットフォームごとにマクロで実装を
切り替えたっていい。

プラットフォームごとの違いを吸収してくれるバイナリ入出力ライブラリ
みたいなものを作ってもいい。

好きにしろ。
573542:2006/04/03(月) 00:51:29
>>572
読み込むにしても、もっとよい策が無いかなぁと思ったものですから、
経験豊富そうな方がいそうなここへ書き込んだしだいです。

少なくとも私の考えた策は処理系依存を気にしないなら使えることが分かりましたし、
可搬性や移植性を考えるならすべきでは無いことも分かりましたので、
後は好きにさせていただきます。
色々と為になる書き込みを戴きました。
どうもありがとうございました。
574デフォルトの名無しさん:2006/04/03(月) 02:05:24
boost::serializationてどうなんだっけ?
575デフォルトの名無しさん:2006/04/03(月) 02:06:13
Boostのテンプレートライブラリ
576デフォルトの名無しさん:2006/04/03(月) 02:17:40
どうせ標準ライブラリの範囲だけでプログラムつくらないから互換性なんか無視っす。
577デフォルトの名無しさん:2006/04/03(月) 09:34:45
>>576 意味不明だな。
578デフォルトの名無しさん:2006/04/03(月) 16:01:05
もう終わった話題だからアレだけど、
例えばWin32 APIなんかだと構造体の最初のメンバが自分自身のsizeofを保持するケースがけっこうある。
先の例のBITMAPINFOHEADERでも、
 unsigned long biSize; // 構造体のサイズ(バイト)
なんてメンバがある。
バイナリ入出力以前に、alignmentをバイト境界にしておかないと、こういうケースでハマると思うんだけど。
(構造体のサイズをハードコーディングするか、#pragmaごにょごにょ)


で、まぁ、なにがいいたいかというと…
alignment、endian、padding、メモリ上のビット表現を考慮し、
各環境で最適なコードで(一気読みできるならそうして、1バイトずつ変換が必要ならそうする)、
ストリームとバイナリ入出力してくれるような
可搬性のあるバイナリ入出力ライブラリ誰か作って…!
579デフォルトの名無しさん:2006/04/03(月) 16:29:45
>>578
バイト境界でなくても整合性さえ取れていれば問題ないと MSDN に書かれてます。
580デフォルトの名無しさん:2006/04/03(月) 20:44:44
>>572
以前実測したが、fstreamとFILE*は、readで一気読みする分には処理速度変わんないよ。
IOがでかすぎるせいで、差が消えちゃう。
581デフォルトの名無しさん:2006/04/03(月) 20:51:43
っていうか fstream や FILE はバッファ有るからまとめてI/Oしてるよね。
Unix の read() や Windows の ReadFile で細かい単位で読み書きしたり
すると、あるべき速度の10倍くらい遅いプログラムも簡単に作ることができる。
582デフォルトの名無しさん:2006/04/04(火) 16:41:00
sort用に、Fooクラスの2つの引数を持つ比較関数オブジェクトを作ろうと思ったのですが、
考えてみれば関数オブジェクトから、Fooクラスのprivateメンバにはアクセスできないっす。
これは一々getter用意するなり、friendにせざるを得ないんすかね。

と、言いますか、operator=や、operator<なんかが、他オブジェクトのprivateメンバにアクセスできるのは、
どの辺に規定されてるんすかね。ドラフト見てもいまいち分からないっす…。
583デフォルトの名無しさん:2006/04/04(火) 16:45:24
>>582
Fooクラスにoperator<を持たせりゃいいじゃん。
それと、operatorなんとかのスコープは関数と同じ。どういう宣言を
されてるかだけによる。
584582:2006/04/04(火) 16:53:28
>>583
レスサンクスです。後者は勘違いしてました。
自分と同じクラスのprivateメンバなら、他オブジェクトでもアクセス出来ちゃうってことすか…。
何か納得いかないすが、理解できました。

何通りかでsortしたいんすが、「Fooクラスにoperator<を〜」では、一つしか賄えなくて困ってるっす。
でもgetterなりしか無いようでしたら、諦めるっす。
585デフォルトの名無しさん:2006/04/04(火) 17:15:03
>>584
関数オブジェクトのコンストラクタに引数をとるという方法は?
引数によって、どういう比較をするか、決めればいいのでは?
586デフォルトの名無しさん:2006/04/04(火) 17:19:21
内部構造を知らないとかけないコンパレータは内部に書くのが普通。
外部から与えるコンパレータが内部構造に依存するのは道理としておかしい

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Foo {
  int a, b;
public:
  Foo(int a, int b) : a(a), b(b) { }
  bool operator < (const Foo& o) const { return cmp_ab(*this, o); }
  static bool cmp_ab(const Foo &lhs, const Foo &rhs) { 
    return lhs.a != rhs.a ? lhs.a < rhs.a : lhs.b < rhs.b; }
  static bool cmp_ba(const Foo &lhs, const Foo &rhs) { 
    return lhs.b != rhs.b ? lhs.b < rhs.b : lhs.a < rhs.a; }
};
int main() {
  vector<Foo> v;
  v.push_back(Foo(0,2));v.push_back(Foo(1,1));v.push_back(Foo(2,0));
  sort(v.begin(), v.end(), Foo::cmp_ab);
  sort(v.begin(), v.end(), Foo::cmp_ba);
}
587デフォルトの名無しさん:2006/04/04(火) 18:13:15
>>586
関数オブジェクトの形にしないでもsortって使えるんですね。
見た目もすっきり。ありがとうございました。585さんもサンクス。
588デフォルトの名無しさん:2006/04/05(水) 18:35:05
皆さんの知恵をお借りしたい。

クラスのメンバ内に次のような宣言があるとします。

public:
  int num0;
  int& operator=(int num1);

int& operator=(int num1); が呼ばれないようにひっそりと num0に
NULL を入れるにはどうやればいいですか?
589デフォルトの名無しさん:2006/04/05(水) 18:41:09
>>588
代入演算子はコピーには適用されなかったと思うからそうすりゃいいんじゃね?
590デフォルトの名無しさん:2006/04/05(水) 18:48:07
class A {
public:
  int num0;
  int& operator=(int num1);
};
main()
{
A a;
a.num0 = 0;
}
591デフォルトの名無しさん:2006/04/05(水) 18:54:37
>>589 コピーには適用されないってどういうこと?
コピーコンストラクタを作れってこと?
592デフォルトの名無しさん:2006/04/05(水) 19:34:03
int& operator=(int num1);
がnum0に代入するときに呼ばれると思ってるのか?
593デフォルトの名無しさん:2006/04/05(水) 21:03:02
一瞬コピーコンストラクタと代入演算子の区別の話だと思ったが
よく読むと全く意図の分からない電波質問だな
594デフォルトの名無しさん:2006/04/05(水) 21:28:33
・int型にNULL
・メンバ変数がpublic
・operator=で何をさせたいのかが不明
595ガウショ:2006/04/05(水) 22:18:01
さて、ここで低レベルな質問です。

char *型の引数で結果を受け取る関数ありますよね?
あれをstd::stringで受け取れるようにしたいです。

理想(無理だけど)↓
string s;
sprintf(s.data(),"aaa");
とか
string s;
GetDlgItemText(hWnd,ID,s.data(),256);

何かいい方法があったら教えて下さい。
596デフォルトの名無しさん:2006/04/05(水) 22:19:23
よくわからんけど、コンストラクタで初期化すればいいんじゃね
597デフォルトの名無しさん:2006/04/05(水) 22:20:54
&s[0]
598デフォルトの名無しさん:2006/04/05(水) 22:23:41
>>595
一時バッファ用意するしか無いと思う。

>>596
わかってなさすぎだと思う。
599デフォルトの名無しさん:2006/04/05(水) 22:24:42
#pragma once
#ifdef __cplusplus
BOOL GetDlgItemText(HWND, std::string&);
#endif
600デフォルトの名無しさん:2006/04/05(水) 22:24:53
>>597
std::stringってvectorの様に連続性が保証されてなかったんじゃなかったっけ?
601596:2006/04/05(水) 22:25:09
>>598
すまん、これ>>588への返答のつもり
602デフォルトの名無しさん:2006/04/05(水) 22:27:44
>>599
特に何も解決してなくね?
603デフォルトの名無しさん:2006/04/05(水) 22:28:16
>>601
コンストラクタで初期化せんでも、単に代入すればいいじゃん。
publicなんだし、num0への代入にoperator=は何も関与しないし。
604デフォルトの名無しさん:2006/04/05(水) 22:31:43
>>603
ひっそりと、っていうからクラスを利用する側に意識させたくないのかと思ったけど
それもそうか
605ガウショ:2006/04/05(水) 22:35:03
>>お答え頂いた皆さん
ありがとうございます!

>>598
やってみます。
606ガウショ:2006/04/05(水) 23:00:39
解決できましたー
607デフォルトの名無しさん:2006/04/05(水) 23:03:53
srand((unsigned)time(NULL));
ransu=rand()%100;
とやっても生成された乱数が同じ数字が三連発されたり等でかなり「つかえねー」のですが
もっとゲームなどに適した乱数関数ってありますか?
608デフォルトの名無しさん:2006/04/05(水) 23:04:53
>>607
Mersenne Twister
609デフォルトの名無しさん:2006/04/05(水) 23:05:27
boost::random
610デフォルトの名無しさん:2006/04/05(水) 23:09:06
>>595
sprintfの代替にはboost::formatがある。

後者は自分でstd::string(というよりもおそらくstd::basic_string<TCHAR>)を受け取る関数を作るしかない。
ただし>>600に注意。

スレ違いな回答をするが、
ATL::CWindow::GetWindowTextならATL::CStringで受け取れる。
またATL::CStringにはFormatというsprintfの代替がある。
MFCのCWndとCStringでも可。
611ガウショ:2006/04/05(水) 23:18:44
コンポジションだっけ?
stringをメンバにして自作クラスつくりまふ。
んでreserveして文字列受け取るメソッド作る。

cString s;
sprintf(s.GetCStr(),"aaa");

みたいな
612ガウショ:2006/04/05(水) 23:33:45
age過ぎましたorz
613デフォルトの名無しさん:2006/04/05(水) 23:40:40
>>611
なんかそんなのboostにあったような無かったような…
614607:2006/04/05(水) 23:43:54
>>608
サンクス。
早速使ってみますた。
あまりの格の差に笑いすらこみ上げますた。

…rand()なんて薦める本は全部焼却処分したい気持ちだw
615デフォルトの名無しさん:2006/04/05(水) 23:47:48
それにしてもここまでstd::ostringstreamが全く出てこないとは……。
616デフォルトの名無しさん:2006/04/05(水) 23:51:12
薦めてる本なんて無いだろ。

boostは標準じゃないんだから、書きたくても書けない。

あと、標準のrandも、実装によってはMTが使われる場合もある。
617デフォルトの名無しさん:2006/04/06(木) 00:27:28
>>607で同じ数値が三連発、というのは
どこかrandの使い方を間違えてるように見えるんだけど

もしかしてrandを使うたびにsrandしてない?
618デフォルトの名無しさん:2006/04/06(木) 01:16:44
はじめまして。
お世話になります。
開発環境:WindowsXP VC++6.0 MFC使用

ダイアログベースで画面を作成(A.exe CDialogベース)し、その画面でボタンを押下し
子画面(A_Child)を表示させます。表示方法はDoModal()で。
そのA_ChildはCDialogベースです。

A_Childダイアログが表示されている間(最前面)は、デスクトップ上の操作を
何も出来ない様にしたいのですが、方法はありますでしょうか?
(例:スタート→ログオフでダイアログが表示しますよね。
その時ってそのダイアログ以外は触れないですよね。)

せめて、自分たちが作成したアプリだけでも操作不可能にしたいのです。
SetWindowPos()、ModifyStyle()、色々試しましたが上手くいきません。
DoModalで表示させるのがそもそもまちがいののでしょうか?

何か方法が有りましたらよろしくお願いします。

説明が下手ですみません。

PS
システムモーダルのチェックONで常に最前面に表示されているのですが
後ろの画面等が操作できてしまうんです・・・・。
619デフォルトの名無しさん:2006/04/06(木) 01:33:30
MFCのモーダルって本当はモードレスで見かけ上モーダルのふりをしてるんだっけ? スレ違いすまそ
620デフォルトの名無しさん:2006/04/06(木) 01:34:41
>>618
スレ違い
621デフォルトの名無しさん:2006/04/06(木) 02:10:35
>>617
そうだな。ありがちなのはtime()が一秒ぐらい同じ値を返すから、srandに3回ぐらい同じ値を
渡してるとか。
622デフォルトの名無しさん:2006/04/06(木) 02:30:12
それとは別に、rand()%100とやるのも良くない。

(int) (100.0 * rand() / (RAND_MAX + 1.0))

のように上位ビットを用いなくては均等な乱数にならない。
623デフォルトの名無しさん:2006/04/06(木) 02:40:23
>>622
最近ではそれを考慮して実装されてるとどこかで聞いた。
ちょいと実験してみる。
624デフォルトの名無しさん:2006/04/06(木) 02:46:07
>>623
operator%を定義してるのかなー、とか考えてしまったではないか・・・w
キニシナイでおくれ
625デフォルトの名無しさん:2006/04/06(木) 04:09:09
operator(・ ・)
みたいなのって定義出来ないの?オッパイ
626デフォルトの名無しさん:2006/04/06(木) 05:51:08
>>616
rand()をMersenne-Twister使って実装してるような処理系あるか?
627デフォルトの名無しさん:2006/04/06(木) 12:00:19
typedef struct {
 double X;     //X座標
 double Y;     //Y座標
} SCoord ;      //座標構造体
vector<SCoord*> CoordsList;   //座標構造体へのポインタ列を格納するベクタ
srand((unsigned)time( NULL ));  //乱数の初期化
for (unsigned int i=0; i<10; i++){
 SCoord* pTempCoord;
 pTempCoord = new SCoord;
 SCoord->X = (double)rand();  //乱数で座標を生成、代入
 SCoord->Y = (double)rand();
 CoordsList.push_back(pTempCoord);
}    //座標構造体のインスタンスを10個作ってポインタを格納

念のためファイルに
ofstreamfout("出力先ファイル.txt");
for (unsigned int i = 0; i < CoordsList.size(); i++){
 SCoord* pTempCoord;
 pTempCoord = (BeadsList[i]);
 fout << "X座標 " << pTempCoord->X << ", Y座標 " << pTempCoord->Y << endl;
}
で出力したところ、正しい値のように見えます。

ここで、pTempCoordはスコープの外ですが、そのポインタはCoordsListに保存
されています。また、newでインスタンスを確保しているので、deleteで開放
するまでメモリが開放されるわけではないと思うのですが、問題あるでしょうか?
628デフォルトの名無しさん:2006/04/06(木) 12:07:59
>>627
問題ない。

>SCoord->X = (double)rand();
pTempCoord->Xの間違いか?
629デフォルトの名無しさん:2006/04/06(木) 13:05:46
>>628
そのとおりです。(__);

630デフォルトの名無しさん:2006/04/06(木) 13:19:42
次の質問です。
typedef struct {
 double X;     //X座標
 double Y;     //Y座標
} SCoord ;      //座標構造体
vector<SCoord*> CoordsList;   //座標構造体へのポインタ列を格納するベクタ
srand((unsigned)time( NULL ));  //乱数の初期化
for (unsigned int i=0; i<10; i++){
 SCoord* pTempCoord;
 pTempCoord = new SCoord;
 pTempCoord->X = (double)rand();  //乱数で座標を生成、代入
 pTempCoord->Y = (double)rand();
 CoordsList.push_back(pTempCoord);
}    //座標構造体のインスタンスを10個作ってポインタを格納

使用済み座標構造体のインスタンスをメモリから削除するつもり
for (unsigned int i = 0; i < CoordsList.size(); i++){
 delete CoordsList[i];
}
CoordsList.clear();   //オートポインタなので不要とは思うが、念のためベクタをクリア

ベクタに格納したポインタは特に放置してもプログラム終了とともに自動消滅するでしょうけど、
構造体のインスタンスはプログラム終了後もメモリに残ると思います。それで構造体のインス
タンスを個別に開放しようとしているのですが、プログラムが異常終了してしまいます。
どこに問題があるのでしょうか?
631デフォルトの名無しさん:2006/04/06(木) 13:54:48
>>630
問題ないようだけど?
> プログラムが異常終了してしまいます
をもっと具体的に。
632デフォルトの名無しさん:2006/04/06(木) 13:56:52
>>630
for (unsigned int i = 0; i < CoordsList.size(); i++){
633デフォルトの名無しさん:2006/04/06(木) 13:59:39
>>632
それの何処に問題が?
634632:2006/04/06(木) 14:03:11
すまんボケてた
635デフォルトの名無しさん:2006/04/06(木) 14:46:18
>>630
>構造体のインスタンスはプログラム終了後もメモリに残ると思います。
OS のないシステムなんですか?

>//オートポインタなので
何が?

で、どこでコケてるんですか?
636デフォルトの名無しさん:2006/04/06(木) 15:06:23
使っている処理系はBorland Developpers Studio 2006のC++Builder10 なの
ですが、デバッガでステップ実行したら、>>630で書いたコードまで終了した
ところで、ソースファイルControls.pasが見つかりません。というダイアログ
が開き、パスを入力するようになりました。
Controls.pasって多分C++BuilderのGUI関連のライブラリのソースで、普通に
インストールすれば、ユーザーが知らなくても処理に必要なら処理系は知ってる
はずと思うのですが...
for (unsigned int i = 0; i < CoordsList.size(); i++){
 delete CoordsList[i];
}
の部分をコメントアウトするとメモリリークしてるかもしれませんが正常終了します。
for (unsigned int i = 0; i < CoordsList.size(); i++){
 SCoord* pTempCoord;
 pTempCoord = CoordsList[i];
 delete pTempCoord;
}

for (unsigned int i = 0; i < CoordsList.size(); i++){
 delete (SCoord*)CoordsList[i];
}
に、変更しても同じなので、ポインタのデータサイズがわからなくなると
いった問題ではなさそうです。
637デフォルトの名無しさん:2006/04/06(木) 15:07:43
実行ファイルを開いた瞬間他のプログラムを開くという処理はどうすればいいのか教えてくれ。
638デフォルトの名無しさん:2006/04/06(木) 15:13:44
system
639デフォルトの名無しさん:2006/04/06(木) 15:14:09
std::systemをmainの先頭からでも呼んだらどうだ?
640デフォルトの名無しさん:2006/04/06(木) 15:24:17
>>636
標準C++の範囲では、見たところソースコードに問題ない。
あくまでも趣味の違いだが、SCoord生成時はnew代入じゃなく初期化時new、削除はイテレータを使うくらいか?:
Sccord* pTempCoord = new SCoord;
for (vector<SCoord*>::iterator it = CoordsList.begin(); it != CoordsList.end(); ++it) delete *it;

Controls.pasは、処理系依存の問題なので、スレ違い。

C++Builder相談室 Part16
http://pc8.2ch.net/test/read.cgi/tech/1138766165/l50
641デフォルトの名無しさん:2006/04/06(木) 15:25:40
いや、>>637は、自分の実行ファイルと入っていない。
何か実行ファイルを開いたとき、他のプログラムを開きたいのだろう。
そして、環境もいわないという傲慢さだ。

そうだなぁ……。
大抵のOSでは、実行するシステムコールもしくはAPIなどがあるから、それをフックして……。
642637:2006/04/06(木) 15:33:49
WinXP VC++6
組みたいプログラムは実行ファイルを開くと他の実行ファイルをオープンさせるという仕組みのプログラムです。
つまり実行ファイルを開いたらブラウザやテキストエディタを起動するようなプログラムを作りたいってこと。
643デフォルトの名無しさん:2006/04/06(木) 15:36:48
だからstd::systemで対象のexe叩けばいいだろ


>>636
C++Builderなんていう腐りきった処理系は窓から投げ捨てろ
644デフォルトの名無しさん:2006/04/06(木) 15:37:48
>>640
ありがとうございました。どうも処理系依存の問題のようですから
C++Builder相談室 Part16に行ってみます。
645デフォルトの名無しさん:2006/04/06(木) 15:44:50
>>643
windows用のC++用開発ツールで、お勧めの腐りきってない処理系って
何ですか?...VC6からC++Builderに逃げ出したのですが...
646デフォルトの名無しさん:2006/04/06(木) 15:45:28
>>642
WinだったらShellExecuteだけど、スレ違いだから他行ってね。
647デフォルトの名無しさん:2006/04/06(木) 15:55:46
>>645 VC++ じゃなんでだめなの?
2005 Express Edition じゃだめ?
648デフォルトの名無しさん:2006/04/06(木) 16:10:17
>>645
別にC++Builderでもいいと思うぞ。
少なくとも、VCLは優れたライブラリだと思う。いささか古い設計ではあるけどね。
今後の発展(標準C++やC++0xへの準拠)はもう望めないけれど、
Win専用GUIつきユーティリティ開発なら悪い選択肢ではない。

漏れはgcc/icc+wxWidgets でもこれは他人におすすめできない。
649デフォルトの名無しさん:2006/04/06(木) 16:19:20
>>647
2005 Express Edition ってVCの新バージョンですか?
乗り換えた頃はVC6で、正確には覚えていないけど、
std::でコンパイルできないことがいくつかあったことと
BCB6にはposix互換関数が揃っていて、UNIXやLinuxへの
移植性があるプログラムが書けると思いました。
IDEのエディタがVCより更にひどかったけど、秀丸を
併用して、セーブしてIDEに戻ると、ソースが変更されました、
読み直しますか?と聞いてくるので、Yes、再コンパイルで
エディタの悪さはカバーできたし...VCLのソースが
パスカルって言うのは気になったけど、ブラックボックスだと
思えばWinMain関数まで隠してしまうMFCよりはましに思えたし...

...で、2005 Express Edition ってBCB10と比べてどういいの?
650デフォルトの名無しさん:2006/04/06(木) 16:21:48
VC++2005は、、、
やたらと重かったりインテリセンスが鈍くて困る
VC++2003から乗り換える理由が見つからん
BCBよりはマシじゃね
651デフォルトの名無しさん:2006/04/06(木) 16:33:53
VC++2005ExpressEdition使ってるけど別に不便なことはない
リソースエディタ付いてないけどそういうの使わないし
てか発売されてるのは高杉
落とせばいいけど開発者としてなんだか悪い希ガス
652デフォルトの名無しさん:2006/04/06(木) 16:44:13
>>651
>落とせばいいけど開発者としてなんだか悪い希ガス
なんで?これMSが無償配布してるんだよね
653デフォルトの名無しさん:2006/04/06(木) 16:46:08
環境依存ネタは他スレでよろ
654デフォルトの名無しさん:2006/04/06(木) 16:47:18
>>652
それとは別の発売されてる方だろ

雑談終了
655デフォルトの名無しさん:2006/04/06(木) 16:50:19
VC6の頃、MSDNプロフェッショナルは、年間7万円弱で、
OSとVSが使い放題だった時期があったけど、今は高すぎ。
OS供給だけのMSDNに入ってる。
656デフォルトの名無しさん:2006/04/06(木) 16:55:27
ここってソースupしたら赤ペン先生してくれますか?
657デフォルトの名無しさん:2006/04/06(木) 16:56:17
たまにしてくれる人もいるよ
暗号化されたソース読むのも勉強になるし
658デフォルトの名無しさん:2006/04/06(木) 17:19:07
boost::format というsprintf 相当のモノはあっても、
sscanf に該当するものがないのは寂しいな。
659デフォルトの名無しさん:2006/04/06(木) 17:20:53
>>658
stringstreamは?
660デフォルトの名無しさん:2006/04/06(木) 17:25:34
>>659
逆だろ
661デフォルトの名無しさん:2006/04/06(木) 17:26:59
あーすまんistringstream忘れてた
662デフォルトの名無しさん:2006/04/06(木) 17:56:03
>>661
いや、stringstream があるのに、boost::format が出来たのは、
マニュピレータの指定が面倒だからでしょ。

たとえば、"0123456789ABCDEF" という入力があったとして、
これを、4桁ずつの16進数と解釈して4つの整数変数に設定したい
みたいな要望があったとき、
sscanf( in, "%4X%4X%4X%4X", out1, out2, out3, out5 );
みたいに型安全に書けたら便利かなってこと。
663デフォルトの名無しさん:2006/04/06(木) 17:58:32
型安全というからには、フォーマット文字列と型が不一致のときは例外でも投げて欲しかった。
664デフォルトの名無しさん:2006/04/06(木) 18:17:29
ありゃ、例外発生しないんだ・・・
これから使ってみようかなと思ってたのに。
665デフォルトの名無しさん:2006/04/06(木) 18:22:43
引数の数が足りないときは例外が投げられるし、投げられないようにも出来る。

>663が言う件では、投げられないとしても問題が無い部分だ。
let's boostの人がそう言ってるから請け売りしてるだけ。
666663:2006/04/06(木) 18:31:29
>>665
let's boost の人がそう言っている、というのは知らなかったな。

まあそれはいいとして、俺は以下のコードはとても気持ちが悪いと
思ってるんだが、問題は無いと思うべきなのか?

try {
cout << format("%06d") % 1.23 << endl;
cout << format("%s") % 1.23 << endl;
} catch (...) {
cout << "catch" << endl; // ここにはこない
}
667デフォルトの名無しさん:2006/04/06(木) 18:34:44
try〜catchの文はあまり頻繁に書きたくない
668デフォルトの名無しさん:2006/04/06(木) 18:54:15
>>666
だったら、xpressive や、spirit の用に Expression Template で
フォーマット書くようなライブラリを使えばいいじゃん。
例外といわず、コンパイル時に警告してくれるぞ。

print( cout, _0d[6] % _endl, 1.23 ); // (int)1.23 でないと警告
print( cout, _s % _endl, 1.23 ); // コンパイルエラー

669デフォルトの名無しさん:2006/04/06(木) 19:08:34
>>668

>>666、は
動的にフォーマットを生成できて、
さらに実行時に型が間違っていれば、
例外を投げてくれるようなものを欲しているのではないか?
670デフォルトの名無しさん:2006/04/06(木) 19:15:10
>>669 の書き込み見てふと気になったんだけど、
書式文字列を動的生成してるひとってどのくらいいるんだろ?

.NET だと自分自身、設定ファイルに書式書き込んでおいて、
読み込むとか(たまに)やるけど、C/C++ だとやった記憶がない。
671デフォルトの名無しさん:2006/04/06(木) 19:21:49
>>670
ひと、じゃなくて場面の問題。俺は割合よくやる。
672デフォルトの名無しさん:2006/04/06(木) 19:35:15
>>670
printf()なら"%*.*s"とかできるから余りやらないけど、scanf()だと融通が利かないからたまにやる。
あー、設定ファイルにフォーマット文字列を書くのはしばしばやるか。
例えば、日付で生成するファイル名を変える場合にFILE_NAME_FORMAT=result_%04d%02d%02d.txtとか。
673デフォルトの名無しさん:2006/04/07(金) 04:23:29
複雑なプリプロセッサマクロを一時的に全て展開して内容を確かめる方法は無いですか?
vc++2005です
674デフォルトの名無しさん:2006/04/07(金) 04:33:25
コンパイラのオプションにあるよ。
プリプロセッサだけ動かすの。
675デフォルトの名無しさん:2006/04/07(金) 05:14:57
>>662
sscanfはおそろしく速いよ。
parserの型を保存した場合だと、spiritもほぼ同じ速さ。
istringstreamは糞。
676デフォルトの名無しさん:2006/04/07(金) 05:25:18
spiritはコンパイルが遅いw
677デフォルトの名無しさん:2006/04/07(金) 06:41:20
>>674 IDE 上で簡単に角にできればいいのにね。
678デフォルトの名無しさん:2006/04/07(金) 09:00:28
>>677
かどにできれば?
かくにできれば?
679デフォルトの名無しさん:2006/04/07(金) 09:22:05
あ〜「確認できれば」のまちがい。
プリプロセッサでの展開後の姿を覗けたらって感じ。
「お前の本性覗いてやるぞ!」
680デフォルトの名無しさん:2006/04/07(金) 09:39:12
マクロ呼び出ししているところをシングルクリックして [F12] で定義をたどることならできるな
681デフォルトの名無しさん:2006/04/07(金) 12:40:56
>>680
きっとBoost Preprocessorみたいな複雑なマクロを書いているのだろう。
682デフォルトの名無しさん:2006/04/07(金) 13:40:34
可変長引数マクロ:
#define F(X, Y, ...) X(Y, __VA_ARGS__)
って、標準C++で対応してたっけ。
g++ 3.4.2は対応してるけれど、標準かどうかがわからず。
683デフォルトの名無しさん:2006/04/07(金) 14:23:59
してない。
684デフォルトの名無しさん:2006/04/07(金) 14:36:48
>>682
vc8でも対応しているから別にいいよそんなこと。
685デフォルトの名無しさん:2006/04/07(金) 19:27:28
変数xの値によって、生成するクラステンプレートの型を変えたい場合にスマートな方法はないでしょうか。

template <typename T>
class C
{
 T value; // 実際にはもっと複雑なクラス
};

enum gen_t { i, d, c };

void f(gen_t type)
{
 switch(type) {
 case i:
  {
   C<int> c;
   g(c); // g()は関数テンプレート
   // ...
  }
  break;
 case d:
  {
   C<double> c;
   g(c);
   // ...

このようにswitch-caseで分岐するしか思いつきません。
686デフォルトの名無しさん:2006/04/07(金) 19:30:46
>>685
変数xって何。その例でいうところの f の引数の type のこと?
687デフォルトの名無しさん:2006/04/07(金) 19:34:40
>>686
すんません、変数xではなくて、fの引数のtypeです。
688デフォルトの名無しさん:2006/04/07(金) 19:42:34
>>687
gen_tは使わなければいけないの?

template <typename T>
void f()
{
C<T> c;
g(c); // g()は関数テンプレート
}

f <int> ();

の方が素直だと思うのだけど
689デフォルトの名無しさん:2006/04/07(金) 19:43:48
>>688
コンパイル時に型が決まんないんでしょ
690デフォルトの名無しさん:2006/04/07(金) 19:53:30
>>685
コンパイル時に型が決まらないテンプレートを使いたいとき、
仮想関数と組み合わせるというテクニックがある。
struct f_base{ virtual void f() = 0; };
template <typename T> struct f : f_base {
  void f() {
    C<T> c;
    g(c);
    // ...
  }
};
691690:2006/04/07(金) 19:54:35
ごめん。struct fのfは別の名前にしておいてくれ。f()はコンストラクタじゃない。
692デフォルトの名無しさん:2006/04/07(金) 20:03:48
>>685

boost::variantでvisitorパターンとか

#include<boost/variant.hpp>
typedef boost::variant<C<int>,C<double>,C<char> > val;
template <typename T> val create(){return val(T());}
val(*table[])()={create<C<int> >,create<C<double> >,create<C<char> >};
struct call_g : boost::static_visitor<>{template<typename T>void operator()(T&t)const{g(t);}};
void f(gen_t type){ 
    val v = table[(int)type]();
    boost::apply_visitor(call_g(),v);
}
693デフォルトの名無しさん:2006/04/07(金) 20:16:13
>>685
enum gen_t { i, d, c };
template <typename T> void h(){
    C<T> t;
    g(t);
}
void(*table[])()={h<int>,h<double>,h<char>};
void f(gen_t type){ 
    table[(int)type]();
}
694デフォルトの名無しさん:2006/04/07(金) 20:47:42
>>688-693
それで教えているつもりか。
まぁヒントぐらいにはなったな。
うむごくろう。

いや、冗談です。マジで参考になります。

>>690氏の仮想関数だと、派生クラス(f_baseを継承したクラス)のインスタンス化は
やっぱりコンパイル時に行われませんか。

>>692-693
インスタンス化された関数ポインタをテーブルで持っておくアイディアは思いつきませんでした。
thxです!
695デフォルトの名無しさん:2006/04/07(金) 21:46:54
>>678
アホ、「すみ」だ
696デフォルトの名無しさん:2006/04/08(土) 01:32:57
>>695
なんだ、つのじゃなかったのか。
697デフォルトの名無しさん:2006/04/08(土) 07:39:42
つのだ☆ひろ
698デフォルトの名無しさん:2006/04/08(土) 12:36:23
>>697

    _, ,_  パーン
  ( ‘д‘)
   ⊂彡☆))Д´) ←>>697
699デフォルトの名無しさん:2006/04/08(土) 16:16:41
列挙型の列挙子にアクセスする際に↓

enum eHoge{TEST0,TEST1};
int i = eHoge::TEST0;

こんな感じで出来ないんですね
700デフォルトの名無しさん:2006/04/08(土) 16:19:04
struct eHoge { enum { TEST0, TEST1 }; };
701デフォルトの名無しさん:2006/04/08(土) 16:19:09
enumは型だから無理だろ
int Zeroに対してint::Zeroとかやってるのと同じ
702デフォルトの名無しさん:2006/04/08(土) 16:27:39
>>701
は?ぁ?
703デフォルトの名無しさん:2006/04/08(土) 16:29:58
>>699 それは非標準ながら VC++ 7.1 なら出来た気がする。
VC++ 8 だとどうかしらん。
704デフォルトの名無しさん:2006/04/08(土) 16:40:29
>>701
バカ?
705デフォルトの名無しさん:2006/04/08(土) 17:21:33
>>703
VC++8ではC++/CLIなら699のようになった。
706デフォルトの名無しさん:2006/04/08(土) 17:52:34
namespaceつかえよ!
707デフォルトの名無しさん:2006/04/08(土) 17:57:48
確かに Enum名::アイテム名 って感じで
値を限定したい気もするよな。
まぁいまさら仕様を変えるのは無理なんだろうけど。
708デフォルトの名無しさん:2006/04/08(土) 18:10:05
struct/namespace eHoge { enum type { TEST0, TEST1 }; };

とか、enum の方にも名前をつけてないと、
型を使いたい時に困るぞい。
709デフォルトの名無しさん:2006/04/08(土) 21:43:18
釣り上手の>>701がいるスレはここですか?
710デフォルトの名無しさん:2006/04/08(土) 21:51:28
いいえ、それはトムです
711デフォルトの名無しさん:2006/04/08(土) 22:10:17
>>710
それどこの英語の教科書?
712デフォルトの名無しさん:2006/04/08(土) 22:14:38
int a = 1;
const long& b = a;

って、キャストで一時オブジェクトができて、その一時オブジェクトを
参照するらしいけど、一時オブジェクトって、その式が終わった瞬間
に消滅するから、この記述は無意味?
713デフォルトの名無しさん:2006/04/08(土) 22:15:43
>>712
うんにゃ
714デフォルトの名無しさん:2006/04/08(土) 22:17:32
constな参照型の変数の構築に使われた一時オブジェクトの寿命は、
その変数の寿命まで引き伸ばされるという規定が無かったっけ?
715デフォルトの名無しさん:2006/04/08(土) 22:29:36
>>712
constの参照の場合、一時オブジェクトはスコープが続く限り
消滅しないだろ。
716デフォルトの名無しさん:2006/04/09(日) 11:25:42
peekmessageループ中でscanf("%s",c)とやってもうまくいかない
(cの値がscanf前後で変わっていないっぽい)のですが
そもそもscanfは「いつ(ex 関数が呼び出されて以降)」から「いつ(ex Enterが呼ばれるまで)」までの
入力を受け取る関数なのですか?

ちなみにこんな感じの使い方です
peekmessage(){



void pushA{//Aキーを押したときの処理
//jyotaiが0のときAを押したらキーボード入力受け取りモードに
   if (jyotai==0){
scanf("%s",c);
 }
}



}
717デフォルトの名無しさん:2006/04/09(日) 12:21:29
標準入力(stdin)でバッファリングされてたりするから
いつからいつまでってないような気がするが。
718デフォルトの名無しさん:2006/04/09(日) 14:04:20
cがcharのポインタであり、更にその参照する領域が確保済みであることを祈るよ。
719デフォルトの名無しさん:2006/04/09(日) 15:23:59
>>716
scnaf()は、関数が呼ばれた時点までに確定している入力を受け取る関数です。
ではいつ入力が確定するかと言うと、標準入力が接続されているデバイスによって違います。
720デフォルトの名無しさん:2006/04/09(日) 15:25:02
>>719
その説明だと入力待ちは生じないように聞こえるが?
721デフォルトの名無しさん:2006/04/09(日) 15:25:24
>scnaf()は、関数が呼ばれた時点までに確定している入力を受け取る関数です。
おまえの環境ではscanfはブロックしないのか?
722719:2006/04/09(日) 15:29:47
すまん。訂正。
関数が呼ばれた時点までに確定している入力がフォーマットの要請に満たない場合、
エラーが発生しない限り待ちますw
723716:2006/04/09(日) 15:48:36
みなさんどうもです。
>>718
char c[81]とVC.netのヘルプのサンプルコードそのままに指定してます。
>>719
ということはpeekmessage中だとキーボードからの入力メッセージはいつまで経っても確定しない?
ってことですかね?
724デフォルトの名無しさん:2006/04/09(日) 18:41:43
>>723
標準入力可能なコンソールプログラムじゃないような気がするが気のせい?


725デフォルトの名無しさん:2006/04/09(日) 23:25:48
effective C++の68ページにmerePoolとmemPoolってあるんですけど。
記述ミスですかね?
726デフォルトの名無しさん:2006/04/09(日) 23:32:05
class A
{
public:
void a1();
void a2(); // <= a1()を内部で使ったメソッド
};

class B : public A
{
public:
void a1(); // <= a1 をオーバーライド
};

この時、オーバーライドしたa1()を使った a2() を呼びたいのですが
このままだと A::a2()が呼ばれます。良い方法はないでしょうか?
727デフォルトの名無しさん:2006/04/09(日) 23:37:20
つvirtual
728デフォルトの名無しさん:2006/04/09(日) 23:37:37
a1を仮想関数にしてオーバーロード
729デフォルトの名無しさん:2006/04/09(日) 23:41:37
class A
{
public:
virtual void a1(); // a1 を仮想関数にして
void a2();
};
class B : public A
{
public:
using A::a1;
void a1(int); // a1 をオーバーロード
};
730デフォルトの名無しさん:2006/04/09(日) 23:46:19
オーバーライドだったっけ?ややこしいな
731デフォルトの名無しさん:2006/04/09(日) 23:49:48
726です。

できました。ありがとうございました!
732デフォルトの名無しさん:2006/04/10(月) 20:10:25
クラスTがあって、T(i)って表記は、どう考えれば良い?

T* a = &T(i);

とかOKなの?
733デフォルトの名無しさん:2006/04/10(月) 20:16:40
OK。問題なし

struct T{T*operator&(){return new T;}};

int main(){
    T i;
    
    T*a=&T(i);
}
734デフォルトの名無しさん:2006/04/10(月) 21:43:59
 T(i) <私まんこちゃん!
  ╋
  /\
735デフォルトの名無しさん:2006/04/10(月) 22:02:10
>>734

    _, ,_  パーン
  ( ‘д‘)
   ⊂彡☆))============= T(i)
  ╋
  /\
736デフォルトの名無しさん:2006/04/10(月) 22:05:57
ふいた
737デフォルトの名無しさん:2006/04/10(月) 22:30:06
>>733>>732の回答としてどうなんだろう?
ひょっとしてネタ?
738デフォルトの名無しさん:2006/04/10(月) 22:52:14
&とTの結合度よりもTと()の結合度の方が高いから、
T(i)はTをiで初期化した一時オブジェクトという意味になるだろう。
739デフォルトの名無しさん:2006/04/10(月) 23:07:19
寿命が問題
740デフォルトの名無しさん:2006/04/10(月) 23:31:31
newした時に一時オブジェクトの内容がコピーされるんでいいんじゃない?
deleteしないとメモリリークするが。
741デフォルトの名無しさん:2006/04/10(月) 23:32:25
ついでに書くと、T(i)と折角書いても、結局operator &()でnew Tが
呼び出されるので、一時変数の内容は無視されている。
742デフォルトの名無しさん:2006/04/10(月) 23:33:47
忘れ去られた>>732……。
743740:2006/04/10(月) 23:37:01
あーしまった。
×newした時に一時オブジェクトの内容がコピーされる
○newした後で折角作った一時オブジェクトがそのまま捨てられてしまう。
 つまりT()でも良いし、T(j) [jはT型のインスタンス]でも全部同じ意味。
744デフォルトの名無しさん:2006/04/10(月) 23:48:06
T a = T();
745デフォルトの名無しさん:2006/04/11(火) 00:27:31
>>742
ちゃんとレスしてるけどね
746デフォルトの名無しさん:2006/04/11(火) 00:58:07
あるオブジェクトのインターフェースで、可変長文字列の可変長配列を処理結果として
返すような場合、一回に1配列分の文字列を返すようにする事が考えられますが、
イテレータとか使って一回で返してしまう方法ってあるんでしょうか?
747デフォルトの名無しさん:2006/04/11(火) 01:08:15
ごめん、732てスタックに積まれたオブジェクトへのポインタを取っているような
気がするけど、間違い無いよね?
748デフォルトの名無しさん:2006/04/11(火) 01:12:21
>746
あまり美しくはないが、auto_ptr<vector<string> >を返すのがパターンかなぁ。
vector<string>を直で返すのはさすがに気が引けるし。
あ、もちろんvectorでなくても適当なコンテナなら何でもいいけど。

他に何かもっと美しい方法あるかね?
749デフォルトの名無しさん:2006/04/11(火) 01:18:24
>>748
std::stringについてのOutputIteratorを取るという方法もある。
面倒だし、異なるイテレータを渡すたびにコードが膨張するという欠点はあるが。
750デフォルトの名無しさん:2006/04/11(火) 01:23:23
>>746
void f(vector<string>& result) じゃダメなの?
751デフォルトの名無しさん:2006/04/11(火) 01:24:23
んー話は変わるけど、動作がわからない物については、デバッグでコンパイルして、
ソースと逆アセンブル混合で見る(VC8)とよくわかるね。

楽ばかりしてないで最終的には規格票を見なきゃならないんだが、あれ全部を
見るのは大変なので、ちょっとした事は上の方法で見ている。バイナリ嘘つかない。
752デフォルトの名無しさん:2006/04/11(火) 01:29:00
>>751
> バイナリ嘘つかない

そうでもないよ。未定義動作になるソースに対しても何かしらコードは出るしね。
あと、人に説明するときに「VC8がこうコンパイルしたから〜」じゃ、さすがに
根拠にならない。おとなしく規格嫁。
753デフォルトの名無しさん:2006/04/11(火) 02:01:58
>748
Sutterお勧めの方法じゃないの?
754デフォルトの名無しさん:2006/04/11(火) 02:40:34
>>748
>vector<string>を直で返すのはさすがに気が引けるし。
TSC計ってみたけど,うち(A),(B)で殆ど差でないけどなぁ
typedef vector <string> Container;
void init_container (Container &p) {
static const size_t container_size (10), string_size (100);
p.reserve (container_size);
for (size_t i (0); i < container_size; ++ i) {
char c ('a'); string s;
for (size_t j (0); j < string_size; ++ j) s.push_back (c ++);
p.push_back (s);
}
}
Container get_container () {
Container result;
init_container (result);
return result;
}
auto_ptr <Container> get_container_ptr () {
auto_ptr <Container> result (new Container ());
init_container (*result);
return result;
}
Container c0 (get_container ()); // (A)
auto_ptr <Container> c1 (get_container_ptr ()); // (B)
755デフォルトの名無しさん:2006/04/11(火) 09:07:13
以下のようにするとエラーがでてしまうのですが、何がいけないのでしょうか?(VC8Expr)

std::vector<char> v;
std::insert_iterator<std::vector<char> > out_itr(v,v.begin());

std::string str("test");
std::copy(str.begin(),str.end(),out_itr);

out_itr = 'a';++out_itr;//ここ
756デフォルトの名無しさん:2006/04/11(火) 09:14:28
*out_itr = 'a';

後,状況によるけれどそのコードでやっていることをやりたいなら
'a' を最初に突っ込んで,次に [str.rbegin(), str.rend()) を
back_inserter に突っ込むほうが効率は良い.
757755:2006/04/11(火) 09:27:24
>>756
ありがとう、ポインタに値代入しちゃだめですね...orz


758デフォルトの名無しさん:2006/04/11(火) 09:34:08
>>757 ポインタじゃないお
759デフォルトの名無しさん:2006/04/11(火) 14:51:12
背伸びする前に、何をやってるかきちんと理解するところからはじめないと。
760デフォルトの名無しさん:2006/04/11(火) 17:33:47
>>759
お前もな。
761デフォルトの名無しさん:2006/04/11(火) 18:03:21
>>760
もちろんそのつもりですがなにか?
762デフォルトの名無しさん:2006/04/11(火) 19:14:44
>>760
>>761
    _, ,_  パーン
  ( ‘д‘)
   ⊂彡☆))Д´) ←>>740, 761
763デフォルトの名無しさん:2006/04/11(火) 22:29:37
伝統的に沸点低いよな、ここ。
764デフォルトの名無しさん:2006/04/11(火) 22:57:03
ポインタなんて、なければいいのに
765デフォルトの名無しさん:2006/04/11(火) 23:04:32
ポインタがわからない PG なんていなくていいのに
766デフォルトの名無しさん:2006/04/11(火) 23:10:53
人の欠点は平気で責めたがるのに、自分の欠点は見ない奴が多いな。
俺もそうだけどな。
767デフォルトの名無しさん:2006/04/11(火) 23:25:44
欠点だから責めてはならないという法はない
致命的な欠点は仕事への責任感に比例して放置できない
全盲の人が機長になれないのと同じ
768デフォルトの名無しさん:2006/04/11(火) 23:30:22
>>767
別に責めてはならないとは言ってない。
ただ人を責める前に自分の欠点を直してからにしろと言いたい。
ある奴の欠点が他人から丸見えなのに、そいつに説教されると腹が立つだろう。
769デフォルトの名無しさん:2006/04/11(火) 23:31:52
致命的な欠点と、仕事はできてる欠点を同列には語れない
770デフォルトの名無しさん:2006/04/11(火) 23:32:27
>>769
わからん奴だな。俺は致命的な欠点については何も言ってない。
お前が勝手に言ってるだけだろう。
771デフォルトの名無しさん:2006/04/11(火) 23:35:12
PG がポインタわかんねーのは、まごうことなき致命的な欠点
治して来てもらう以外に打つ手はない
772デフォルトの名無しさん:2006/04/11(火) 23:36:29
>>771
それを先に言え馬鹿。
何の一般論かと思ったぜ。
773デフォルトの名無しさん:2006/04/12(水) 00:17:06
流れ嫁。
774デフォルトの名無しさん:2006/04/12(水) 00:41:58
全ての型に文字列変換するインターフェースを付けたくて
struct IStringifiable{
  virtual string toString() const = 0;
  virtual void Parse(const string& source) = 0;
};
template < typename T > struct Stringifiable : public T, public IStringifiable{
  virtual string toString() const { 云々かんぬん… }
  virtual void Parse(const string& source) { 云々かんぬん… }
};
なんてことをしたら Stringifiable< int > みたいにしても
プリミティブ型を継承できなくて('正しい基本クラスではない'と怒られる)困っています。
この場合StringifiableクラスのメンバーにT型のインスタンスを持つしかないんでしょうか?
775デフォルトの名無しさん:2006/04/12(水) 00:43:25
>>774
その通り。
776デフォルトの名無しさん:2006/04/12(水) 00:44:19
何したいのかわからん。
777デフォルトの名無しさん:2006/04/12(水) 00:51:02
>>774
string StringFrom(T source);
void ParseTo(T& target, string source);

int と Stringifiable についてオーバーロードするか、
template にして特殊化すればいいんじゃね?
778774:2006/04/12(水) 01:01:26
INIファイルやらコマンドラインやらからの入力に対応できる変数
みたいなモノを考えてました

例えば繰り返す回数をStringifiable< int > repeat_countみたいに定義しておいて

 IIniFile::Bind("ファイル名", "セクション名", "キー名", repeat_count);
 ICommandLine::Bind("コマンドライン名", repeat_count);

といった感じに関連付けておけば

 IIniFile::Load("ファイル名");
 ICommandLine::Eval(lpCmdLine);

とやった時に変数の内容が更新されているような。
これをメンバー変数でやるようにしてしまうと repeat_count = 10;
という式が書けなくなってしまうのでなんだかな〜と思ったわけです。

あ、operator const T() constとoperator=(const T& source)を
オーバーロードすりゃいいのかな?
779デフォルトの名無しさん:2006/04/12(水) 01:11:04
template<typename T> string ToString( const T& );
と宣言しといて、
template<> string ToString( const struct Hage& arg ){
//argを文字列に変換するコード
}
みたいなのを文字列に変換したい型の数だけ実装して、
strunt Hage a = {〜〜〜};
string hageStr = ToString(a);
みたいに使えばよくね?
780774:2006/04/12(水) 01:48:21
>>779
いや、それだとバインドができないので…


とりあえず>>778の最後の解決法でやってみてるけど
ユーザー定義型についてStringifiableのメソッドを特殊化してもらうときに
メンバー変数名がわかってないと書けないのは気持ち悪いなぁ
781デフォルトの名無しさん:2006/04/12(水) 01:58:29
int repeat_count;と定義して、
IIniFile::Bind("ファイル名", "セクション名", "キー名", &repeat_count);
という風に使うインタフェースのほうがきれいじゃないだろうか。
Bindをいちいちテンプレートにするのが嫌なら、
IIniFile::Bind("ファイル名", "セクション名", "キー名", make_stringfier(&repeat_count));
とか。
782774:2006/04/12(水) 02:26:45
>>781
Bindの中でrepeat_countを参照で持つStringifiableのインスタンス作って
それを保持しとけば良いってことかな?
IIniFileとかの中ではいじくりたい変数の型を意識したくないので
なにかしらインターフェースを噛ませる必要があるのだけども

今後テキストエディットからの入力とか、外部から文字列で飛んでくる値を
全部透過的に扱うつもりなんだけど、受け取りたい対象毎に
(INIファイル用、コマンドライン用、エディタからの入力用…etc)
Stringifiableのインスタンスがどんどん増えてくのはどうなんだろう…

ちなみに後出しになって申し訳ないけどソースコード上である変数が
外部から書き換えられる可能性がありますよと明示したい意図もあったりして
説明のため直感的な名前にしたけどほんとはIStringifiableじゃなくて
IConfigurableってインターフェース名です
783デフォルトの名無しさん:2006/04/12(水) 02:34:38
もう質問は無いな。がんばれよ。

はい次の人どうぞ。
784デフォルトの名無しさん:2006/04/12(水) 18:02:37
>>779
それだったら、operator <<と>>を作ってboost::lexical_castでよくね?
785デフォルトの名無しさん:2006/04/12(水) 19:06:14
>>778 どうよ?

// 文字列 => 変数への変換
template< typename T > struct parser {
 void operator()( T & dest, string const & src ) const {
  dest = ::boost::lexical_cast< T >( src );
 }
};
// データバインドを行う
struct data_binder {
 ::boost::function< void ( string const & ) > update;
 template< typename T > void bind( T & value ) {
  update = ::boost::bind( parser<T>(), value, ::boost::bind::_1 );
 }
};
// 派生クラス
class ini_file : data_bindable {
 static map< path, data_binder > content;
public:
 template< typename T >
 static void bind( string const & fn, ...中略..., T & value )
 {
  path x( fn, section, key ); // パスを作成
  content[x].bind( value ); // バインド完了
 }
 static void load( string const & filename ) {
  /* 何かループ */ {
   // TODO: データ読み込み
   content[ /*パス*/ ].update( /*読み込んだデータ*/ );
  }
 }
};
786785:2006/04/12(水) 19:10:23
あ、ini_file のベースになってる data_bindable は何の意味もないな。
忘れてくれ。
787デフォルトの名無しさん:2006/04/13(木) 08:57:51
スタックオーバーフローの例外が発生するのですが、こういうものなのでしょうか?

struct SList
{
boost::shared_ptr<SList> next;
};

int main(){
SList a;
SList* p = &a;
for(int i=0;i<100000;i++){
p->next = boost::shared_ptr<SList>(new SList);
p = p->next.get();
}
}
788デフォルトの名無しさん:2006/04/13(木) 09:04:18
>>787
cygwin g++ 3.4.4 で試したけど、何事も無く終了したよ。
789デフォルトの名無しさん:2006/04/13(木) 09:31:00
>>787
SList のデストラクタが全要素分再帰的に呼び出されることになるので、
デストラクタ呼び出しごとのスタック消費の 100000 倍のスタックが必要になる。

環境が書いてないことから想像すると Win32 で VC のデフォルト設定だろうから
スタックが 1M バイト割り当てられていたとして、1回のデストラクタ呼び出しによる
スタック消費が 10 バイト以内( 2 ワード以内)に収まっていればいい計算だが、微妙だな。
790787:2006/04/13(木) 09:39:03
>>788
VC8Expressなんですが、
コンパイラオプションから/clrをはずしたらうまくいきました。
バグなのかな...
791デフォルトの名無しさん:2006/04/13(木) 09:49:31
>>790
CLR が挟まってるならスタック消費が 2 ワードじゃ済まなさそうだな。納得。
792785:2006/04/13(木) 10:05:38
>>785 の data_binder は↓のようにしないとダメだな。
_1 がいつの間にか無名NSに移動してたのは驚いた

// データバインドを行う
struct data_binder {
 ::boost::function< void ( string const & ) > update;
 template< typename T > void bind( T & value ) {
  update = boost::bind( parser<T>(), boost::ref(value), _1 );
 }
};
793デフォルトの名無しさん:2006/04/13(木) 10:07:55
ぶぅすとってオイシイ?
794デフォルトの名無しさん:2006/04/13(木) 10:17:33
はい、オイシイです
795デフォルトの名無しさん:2006/04/13(木) 10:20:49
あれあれ?怒らせていいんですか?使いますよ。イオナズン。
796787:2006/04/13(木) 10:21:13
>>789
>>791
デストラクタが深い再帰にならないようにしないといけないんですね。
(/clrだとi=4393までしかいけませんでした。)
797デフォルトの名無しさん:2006/04/13(木) 13:19:23
小ブロック程度のnewで、メモリを確保できないって事あるんですかね?
一般的な環境(Win Mac Linux辺り)で

なんか丁寧に例外取ってるの馬鹿らしくなってきまして
798デフォルトの名無しさん:2006/04/13(木) 13:28:35
>>797
メモリが有限の資源である以上ある。
丁寧に例外を取るって何やってるか知らんが、多分間違った考え方してる。
799デフォルトの名無しさん:2006/04/13(木) 13:36:24
>>798
もちろんnewする度にそこでtry-catchしている訳ではなく、メモリ確保できなかったら、
中間層辺りcacthし、データをバックアップする程度なんですが。

仮想メモリもあるし、それすら使い果たす頃には
例外取ってバックアップどころじゃない気もするんですよね
800デフォルトの名無しさん:2006/04/13(木) 13:55:10
こんなかんじですKA?(><)

hevy_weight * p = 0;
try {
 p = new hevy_weight();
}
catch( std::bad_alloc const & ) {
 throw std::runtime_error("メモリ不足です!");
}
801デフォルトの名無しさん:2006/04/13(木) 13:55:51
スタックの話でなかったの?
802デフォルトの名無しさん:2006/04/13(木) 14:35:09
ちがうやつじゃね?
そしてheavyなスペル違うぞ
803デフォルトの名無しさん:2006/04/13(木) 15:17:40
>>800 は heavy のスペル違うけど、ひょっとして
メモリ不足で bad_alloc 投げてるのに、ヒープに文字列保存する runtime_error 投げんのかよ!?
みたいな感じでは?
804デフォルトの名無しさん:2006/04/13(木) 17:38:23
>>799
一般向けOSだとメモリはページ単位(4KBとか)で確保するものが多いから
それ以下のメモリ要求に対し失敗したらruntime_errorも投げれなそう。

漏れの個人的テストだと、小ブロックの確保時にbad_allocが投げられることはあるけど、
わざとそういう状況を作るか、プログラムのバグでHDDが異常にガリガリ言った後に投げられるか、
いずれにしても例外が投げられる前から予想できるときにしか投げられなかった。

そこで、bad_allocに対してtry〜catchをするのではなく、予期しない例外のひとつとしてcatch(...)。
むしろbad_allocより、制御装置固有のとか、特定用途の例外を知りたいわけで。
805797 799:2006/04/13(木) 18:36:29
800さんは別の方です

>>804
勉強になります。貴重な情報感謝。
なるほど、確保失敗時は厳しいので、細かくやらず大きいくくりで捉えておこうという訳ですか。
ありがとうございました。
806デフォルトの名無しさん:2006/04/13(木) 23:11:28
windowsの「メモリがありません」ダイアログに頼ってます。
807デフォルトの名無しさん:2006/04/14(金) 14:48:58
最近boostを勉強しはじめたんですが、shared_ptrに入っているオブジェクトのポインタを
ダウンキャストしたい時はどうすればいいんでしょうか?
(例)
class foo{};
class bar : public foo{};
typedef boost::shared_ptr<foo> pfoo;

foo* b1 = new bar();
pfoo b2 = pfoo(new bar());

// b1なら、
if (dynamic_cast<bar>(*b1)) cout << "this is bar1" << endl;

// b2だと?
if (dynamic_cast<bar>(*b2)) ; // error!
808デフォルトの名無しさん:2006/04/14(金) 14:53:18
>>807
訂正
if (dynamic_cast<bar*>(b1)) cout << "this is bar1" << endl;
809デフォルトの名無しさん:2006/04/14(金) 14:56:34
諸君、活発に議論しているかね?
810デフォルトの名無しさん:2006/04/14(金) 14:58:11
dynamic_cast<bar&>(*b2)
811デフォルトの名無しさん:2006/04/14(金) 15:09:06
>>807
dynamic_cast<bar*>(b2.get())

fooのデストラクタがvirtualになってないよ。
812デフォルトの名無しさん:2006/04/14(金) 15:22:29
>>811
b2.get()でいけました。 ありがとう
fooのデストラクタは、例では書かなかったけど作ってるプログラムはvirtualになってます。
813デフォルトの名無しさん:2006/04/14(金) 16:38:36
>>807
専用のキャストが用意されています.

http://www.boost.org/libs/smart_ptr/shared_ptr.htm#dynamic_pointer_cast

あと蛇足ですけれど, shared_ptr<foo>(new bar()) な形で shared_ptr を
生成していればデストラクタが virtual でなくても bar のデストラクタが走ります.
814デフォルトの名無しさん:2006/04/14(金) 16:41:45
>>812
もう遅いかもしれないが、shared_ptr 専用の

shared_static_cast
shared_dynamic_cast
shared_polymorphic_cast
shared_polymorphic_downcast

が定義されている。
上の例だと、

if( shared_polymorphic_downcast<bar>(b2) )

でもいい。
815デフォルトの名無しさん:2006/04/14(金) 16:48:28
>>813>>814
おぉ、ありがとう。 専用のがあるんですね。
そっち使うことにします。
816デフォルトの名無しさん:2006/04/14(金) 19:27:50
質問なんですが、Windows付属のペイントソフトでブラシの太さ(堅さ?)を3段階で選べますよね?
あれをユーザが0から100の値で選べるようにするにはどういうコードを書いたらいいんでしょうか?
817デフォルトの名無しさん:2006/04/14(金) 19:32:11
>>816
スレ違い
818デフォルトの名無しさん:2006/04/14(金) 19:34:35
>>817
すいませんでしたorz
819デフォルトの名無しさん:2006/04/14(金) 19:58:43
820816:2006/04/14(金) 20:11:17
>>819
ありがとうございます!
821デフォルトの名無しさん:2006/04/15(土) 11:46:33
boost::shared_ptrで質問です。

class hoge; // forward
boost::shared_ptr<hoge> PHoge;
class hoge
{
  [※1] owner;
  vector<PHoge> hoges;
};
こんなクラスがあるとき、
あるhogeオブジェクトAOwnerと、
AOwnerに所有されている、AOwnedがあるとき、
AOwnerのvector hogesに、AOwnedが入り、
AOwnedのownerにAOwnerを指すポインタを持ちたいとき
AOwnedのownerはweak_ptrにする必要があるのでしょうか?

boost::shared_ptrの循環参照の説明読んでたら頭が混乱してしまいました。
822デフォルトの名無しさん:2006/04/15(土) 12:37:50
ゲ製から誘導されて

あちこち探し回っても、的確な答えが見つからないので

C++の話だが、
SaveDigit(FILE* stream, int nData);
LoadDigit(FILE* stream, int* nData);
名前の通り、int型のファイル入出力を行う関数があるのだが、
COLORREFやDWORDやunsigned intをこの関数で保存したい場合、
当たり前だがキャストが必要になる。

このキャストの時、データは破壊されないのだろうか?
それとも、各型毎の関数を作るかテンプレート関数を作るべき?
823デフォルトの名無しさん:2006/04/15(土) 12:40:04
>>822
各型のサイズやビットパターンは環境依存
824デフォルトの名無しさん:2006/04/15(土) 12:54:24
>823
サンクス、危うく環境依存のバグを埋め込むとこだった…orz
825デフォルトの名無しさん:2006/04/15(土) 13:38:33
std::vector<Hoge> container;
boost::ptr_vector<Hoge> ptr_container;

containerからptr_containerに内容をコピーしたいのですが
std::copy(container.begin(), container.end(), std::back_inserter(ptr_container));
ではptr_container.push_back()がHoge*を要求するのでできません。
newしてpush_backするback_insert_iteratorを作る以外で何か方法ありませんか?
標準 or Boostにあるものを使って書ければベストなのですが。
826デフォルトの名無しさん:2006/04/15(土) 13:49:30
newする関数オブジェクトを書いてstd::transform
827デフォルトの名無しさん:2006/04/15(土) 13:51:45
using namespace boost::lambda;
std::transform(container.begin(), container.end(),
std::back_inserter(ptr_container), new_ptr<Hoge>(_1));
828825:2006/04/15(土) 14:05:34
あ、transformですか。copyという事に執着してました。
push_backイテレータ作るよりはシンプルですね。
これで行きます。ありがとうございました。
829デフォルトの名無しさん:2006/04/15(土) 22:30:07
質問があるんですが、VC++とC++は違うんでしょうか?
いやですね、C++を学習するつもりで本を買ったのですがVC++を買ってました。
C++を学ぶならC++のやつを買いなおした方がいいでしょうか?
830デフォルトの名無しさん:2006/04/15(土) 22:44:34
>>829
ありゃ、マルチかい…。あっちに答えといたよ。

スレッドを立てるまでもない質問雑談スレ23
http://pc8.2ch.net/test/read.cgi/prog/1139729337/839
831デフォルトの名無しさん:2006/04/16(日) 22:11:16
オラに10日でC++ヲミニツケルチカラヲクレ
832デフォルトの名無しさん:2006/04/16(日) 22:15:10
>>831
つ精神と時の部屋
833デフォルトの名無しさん:2006/04/16(日) 22:20:27
831じゃないけどC++勉強したいけどどこから手をつけていいのか解らなくて
右往左往してる弱った....
834禿@ベル研究所 ◆HsptrkZmYk :2006/04/16(日) 22:24:29
まずは漏れの本を読め。
話はそれからだ。
835デフォルトの名無しさん:2006/04/16(日) 22:31:15
Cを知ってるなら簡単だろ
STLやクラスの高度な機能は後回し
836833:2006/04/16(日) 23:47:41
ループとか標準関数とかはわかったけど
ここからどうすればいいの?
何かね課題みたいにプログラム作りたいんだけど
なんかいい例ない?1万ステップぐらいのやつがいいんだけど
837デフォルトの名無しさん:2006/04/16(日) 23:57:30
だれかヘルプミー。

g++ 3.4.4 (cygwin special)で以下のコードをコンパイルしたら、

#include <fstream>

bool pattern::read(std::ifstream& ifs)
{
  int w;
  ifs >> w;
}

こんなエラーがでました。

pattern.cpp: In member function `bool pattern::read(std::ifstream&)':
pattern.cpp:39: error: no match for 'operator>>' in 'ifs >> w'

intに対しては operator>> は(cinと同様に)定義されてると思うんだけど……。
なんか不味いことしてますか?
838デフォルトの名無しさん:2006/04/17(月) 00:27:20
>>837
そのコードは pettern の宣言が無いというエラーになった。

エラーの出るソースはそれだけじゃないだろ。
問題が再現できるコードをちゃんと作れ。
839837:2006/04/17(月) 00:53:23
>>838
すみませんでした。正確には以下の通りです。

#include <iostream>

class pattern{
public:
  bool read(std::ifstream&);
};

bool pattern::read(std::ifstream& ifs)
{
  int w;
  ifs >> w;
}
840デフォルトの名無しさん:2006/04/17(月) 00:55:27
>>839
× iostream
○ fstream

再現コード作ってるときに気付くのが、よくあるパターンなんだがな。
841デフォルトの名無しさん:2006/04/17(月) 00:57:28
>>836
1万ステップは無いと思うが、課題が欲しいなら↓こんなスレがある。

C/C++の宿題を片付けます 63代目
http://pc8.2ch.net/test/read.cgi/tech/1143405137/
842デフォルトの名無しさん:2006/04/17(月) 01:05:56
>>840
うう、ifstreamは<fstream>ですね。
恐ろしく凡ミスに答えてくださってアリガトウございます。
全くお恥ずかしい限りで……。
843デフォルトの名無しさん:2006/04/17(月) 04:58:33
new ch[10];

などとして確保したバッファ領域にデータを代入した後、そのデータはそのままに、
おしりに、さらに10バイト分のデータを追加したい場合、Cだと realloc()で、代入
データをそのままに、メモリー領域を拡大できますが、new した場合はそのような
事はできませんか?

できない場合は、別途 20バイト分newして、そこにそれぞれをコピーして繋げる
しかないでしょうか?
844デフォルトの名無しさん:2006/04/17(月) 04:59:04
new ch[10] -> new char[10]の間違いでした。
845デフォルトの名無しさん:2006/04/17(月) 05:28:34
>>843
その通り。realloc()を使わない方が良いのは、delete演算子で
デストラクタが働く事があるためです。
846デフォルトの名無しさん:2006/04/17(月) 05:29:25
いや、むしろ
×realloc()を使わない方が良いのは
○realloc()を使ってはいけないのは
847デフォルトの名無しさん:2006/04/17(月) 08:53:06
>>843
先ずはnew/deleteを使う戦略を見直す。
例えば、vectorなら何も悩む必要がなくなる。
848デフォルトの名無しさん:2006/04/17(月) 09:36:58
一応デストラクタを自前で呼ぶ事もできるけど、
そこまでパフォーマンスを追求する(realloc を使う)必要性があるか、だな。
849デフォルトの名無しさん:2006/04/17(月) 19:24:35
>>841
そこほとんどCじゃんw
たまに、悪ふざけしているような回答者がC++でコード書いてるけど

というか、まあ、どうやって身に付ければいいんだろうね
おれは適当に本読んで、プログラム書いたりしてるけど
細かいところの知識があちこち欠けている気がする
ADLとか
850デフォルトの名無しさん:2006/04/17(月) 19:27:43
まともでそこそこなアプリ作ろうとしたら軽く1万いきそうだけど・・・
851デフォルトの名無しさん:2006/04/17(月) 19:33:34
>>849
それを題材としてC++で組め、っていう話だろう・・・
852デフォルトの名無しさん:2006/04/17(月) 23:25:41
Aというクラスがあったとして、
A* pa1 = new A();
A* pa2 = new A;
この2つの命令に何か違いはあるのでしょうか。

同じ意味だとは思うんですが、確信が持てないです。
ちょっとした違いでもあれば教えて下さい。

delete pa1;
delete pa2;
853デフォルトの名無しさん:2006/04/17(月) 23:41:28
>>852
前者は0フィル。
後者はデフォルト・コンストラクタが呼ばれる。
854デフォルトの名無しさん:2006/04/17(月) 23:42:22
あ。もちろん前者も0フィルの後デフォルト・コンストラクタが呼ばれる。
855デフォルトの名無しさん:2006/04/17(月) 23:48:36
0で初期化なんてあったっけ?
856852:2006/04/17(月) 23:56:12
>>853
実際に試してみたんですが、どちらも初期化されてませんでした。
C++言語仕様ではそうなっていて、私の環境では仕様に沿ってない実装ってことになるのでしょうか。

それとも他の意味があるのかな。
857デフォルトの名無しさん:2006/04/17(月) 23:56:39
C#と混同してるんだろ。
858852:2006/04/18(火) 00:01:36
確かに、C#はフィールドを初期化しますね。
なかなか素敵な言語仕様です。

結局、上で挙げた2つは全く同じだ、ということになるんですかね。
859デフォルトの名無しさん:2006/04/18(火) 00:01:52
§5.3.4.15
15 A new-expression that creates an object of type T initializes that object as follows:
. If the new-initializer is omitted:
. If T is a (possibly cv-qualified) non-POD class type (or array thereof), the object is defaultinitialized
(8.5). If T is a const-qualified type, the underlying class type shall have a user-declared
default constructor.
. Otherwise, the object created has indeterminate value. If T is a const-qualified type, or a (possibly
cv-qualified) POD class type (or array thereof) containing (directly or indirectly) a member of
const-qualified type, the program is ill-formed;

という事で、非POD型はデフォルト・コンストラクタ、POD型は不定値。
860デフォルトの名無しさん:2006/04/18(火) 00:04:52
追加

. If the new-initializer is of the form (), the item is value-initialized (8.5);
. If the new-initializer is of the form (expression-list) and T is a class type, the appropriate constructor is
called, using expression-list as the arguments (8.5);
. If the new-initializer is of the form (expression-list) and T is an arithmetic, enumeration, pointer, or
pointer-to-member type and expression-list comprises exactly one expression, then the object is initialized
to the (possibly converted) value of the expression (8.5);
. Otherwise the new-expression is ill-formed.

で、§8.5を見てみると・・・・

8 [Note: since () is not permitted by the syntax for initializer,
X a();
is not the declaration of an object of class X, but the declaration of a function taking no argument and
returning an X. The form () is permitted in certain other initialization contexts (5.3.4, 5.2.3, 12.6.2). ]
861デフォルトの名無しさん:2006/04/18(火) 00:09:10
5 To zero-initialize an object of type T means:
. if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;
. if T is a non-union class type, each nonstatic data member and each base-class subobject is zeroinitialized;
. if T is a union type, the object’s first named data member89) is zero-initialized;
. if T is an array type, each element is zero-initialized;
. if T is a reference type, no initialization is performed.
To default-initialize an object of type T means:
. if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is
ill-formed if T has no accessible default constructor);
. if T is an array type, each element is default-initialized;
. otherwise, the object is zero-initialized.
To value-initialize an object of type T means:
. if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is
called (and the initialization is ill-formed if T has no accessible default constructor);
. if T is a non-union class type without a user-declared constructor, then every non-static data member
and base-class component of T is value-initialized;

という事で、A()の形は非POD型はデフォルト・コンストラクタ、POD型はzeroで初期化される。
ここがAという形とは違う唯一の点か。
862デフォルトの名無しさん:2006/04/18(火) 00:15:10
ごめん>>860は不要。>>859>>861だけ見てね。

#include <iostream>

struct A {
int a;
};

int main()
{
int* pi1 = new int();
int* pi2 = new int;
A* pa = new A();
A* pb = new A;

std::cout << *pi1 << std::endl; // ここだけ必ず 0
std::cout << *pi2 << std::endl;
std::cout << pa->a << std::endl;
std::cout << pb->a << std::endl;

delete pb;
delete pa;
delete pi2;
delete pi1;
}
863852:2006/04/18(火) 00:21:46
なるほどなるほど。
これからは、new intに()をつけようって思いました。
ありがとうございました。
864デフォルトの名無しさん:2006/04/18(火) 00:35:30
#include <iostream>

struct A {
int a;
};

struct B {
int b;
void print() const {
std::cout << b << std::endl;
}
private:
virtual void f() {} // 非PODにする
};

int main()
{
int* pi1 = new int();
int* pi2 = new int;
A* pa = new A();
A* pb = new A;
B* pa2 = new B();
B* pb2 = new B;

std::cout << *pi1 << std::endl; // ここは必ず 0
std::cout << *pi2 << std::endl;
std::cout << pa->a << std::endl; // ここも必ず 0
std::cout << pb->a << std::endl;

pa2->print(); // もはや0である保証はない
pb2->print();
865デフォルトの名無しさん:2006/04/18(火) 00:35:43

delete pa2;
delete pb2;
delete pb;
delete pa;
delete pi2;
delete pi1;
}
866デフォルトの名無しさん:2006/04/18(火) 00:42:49
俺も知らなんだ。

便乗して

char p[] = "123456";
new(p) char[3](); // 先頭3つだけ0にセット

これもあり?
867デフォルトの名無しさん:2006/04/18(火) 01:49:42
>>863
そもそもintをnewすることがナンセンス。
868デフォルトの名無しさん:2006/04/18(火) 01:50:54
>>866 おk

#include <iostream>
#include <algorithm>

void print(int i) {
std::cout << i << ' ';
}

int main()
{
char p[] = "123456";
new(p) char[3](); // 先頭3つだけ0にセット

std::for_each(p, p + sizeof(p), print);
}
869デフォルトの名無しさん:2006/04/18(火) 01:56:34
配置newってdeleteしなくていいの?
870デフォルトの名無しさん:2006/04/18(火) 02:09:59
>>869
配置newで配置したオブジェクトがデストラクタを持っている時だけ
呼び出す必要がある。

というか、char[3]ってデストラクタないでしょう。呼び出したくても
呼び出せない。
871デフォルトの名無しさん:2006/04/18(火) 02:14:24
まさか delete p; したいとか?
そんな事は思ってないよね?
872833:2006/04/18(火) 02:20:17
delete char[3] したいです。
new char[3]できるからしたいです
873デフォルトの名無しさん:2006/04/18(火) 02:34:03
>>872
やっても構わないけど、undefinedだよ。鼻から悪魔が出てくるかも。

new char[3] と new(p) char[3] の違いをもう一度調べてみよう。
874デフォルトの名無しさん:2006/04/18(火) 04:18:19
>>862
> std::cout << pa->a << std::endl;
↑ここも必ず 0 じゃね?

>>864
> pa2->print(); // もはや0である保証はない
↑ここも必ず 0 じゃね?
new B() は "value-initialized" で B は
"a class type with a user-declared constructor" じゃなくて
"a non-union class type without a user-declared constructor" だから
pa2->b は "value-initialized" → "zero-initialized" で 0 になるだろ。
875デフォルトの名無しさん:2006/04/18(火) 04:59:51
型を返す非static関数は書けますか?
876デフォルトの名無しさん:2006/04/18(火) 05:11:07
>>875 「型を返す」の意味がわからん。
877デフォルトの名無しさん:2006/04/18(火) 05:21:33
>>874
そう思うならやってみろや。
わざわざ仮想関数を入れてnon-PODにしている意味がわからないのか?
878デフォルトの名無しさん:2006/04/18(火) 09:08:41
>>875
直接に型は返せないが、
ポリモーフィズムや列挙型を使って
それなりのことはできる。
879デフォルトの名無しさん:2006/04/18(火) 09:11:10
そこでthisポインタをthrowですよ。
880デフォルトの名無しさん:2006/04/18(火) 09:13:56
お前等エスパーだな。
881デフォルトの名無しさん:2006/04/18(火) 09:18:04
オブジェクトへの参照を返しながら
そのオブジェクトをこっそり delete するのって、
登り掛けてる人のハシゴはずすみたいで
いたずらっぽくて楽しいよな。
882デフォルトの名無しさん:2006/04/18(火) 09:25:09
>>879
型が分からなければcatchできないのでは?
883デフォルトの名無しさん:2006/04/18(火) 09:26:49
>>879
パフォーマンスを度外視すれば確かに
型を返したと言えるね。
884876:2006/04/18(火) 09:39:17
自己解決しましたwww
885デフォルトの名無しさん:2006/04/18(火) 10:02:54
>>875
type_info か?
886デフォルトの名無しさん:2006/04/18(火) 10:09:51
>>877
とりあえず g++ でやってみたら全部 0 になったわけだが。
規格の話をしてるんだから、自分の持ってるコンパイラの
実験結果がわかっても意味無いだろ。

POD かどうかは "a class type with a user-declared constructor" にも
"a non-union class type without a user-declared constructor" にも関係ないから
意味がわからん。
887デフォルトの名無しさん:2006/04/18(火) 10:26:38
>>885
あまりにも使わないので、存在を忘れかけていた。
888デフォルトの名無しさん:2006/04/18(火) 10:31:06
型情報じゃなく、型そのものを返す関数やクラスは作成できないものか、という意味でした。
考えてたら夜があけてしまい、2chに質問書いて寝ていま起きましたスンマセン
889886:2006/04/18(火) 10:38:39
struct A
{
  int a;
// virtual ~A();
};
A* f() { return new A(); }

こんなコードのアセンブリ吐かせてみた。
cygwin gcc 3.4.4 では non-POD にすると a は初期化されなかった。

とりあえず、 value-initialized に頼るのはまだまだ危険みたいだな。
だれか他のコンパイラの対応状況をレポートしてくれると助かる。
890デフォルトの名無しさん:2006/04/18(火) 10:39:48
>>888 だから、意味がわかんねぇって。 C++ でおk
891デフォルトの名無しさん:2006/04/18(火) 10:56:16
型は返せません、以上。
892デフォルトの名無しさん:2006/04/18(火) 11:02:05
template でメタプログラミングしてることも考えると、そうとも言い切れない。
875 や 888 は、絶対違うだろうけど。
893デフォルトの名無しさん:2006/04/18(火) 11:17:57
>>888
どういう使いかたを想定している?
894デフォルトの名無しさん:2006/04/18(火) 11:30:34
多分、こんな使い方を想定してるんだろう。

type foo() {
 return int;
}

type t = foo();
t n = 0;
cout << n << endl;

まあ、直接は無理だな。
近い事はできるかもしれんが。
895デフォルトの名無しさん:2006/04/18(火) 11:34:32
実はファンクタを作りたいだけだったりして。
896デフォルトの名無しさん:2006/04/18(火) 11:41:56
>>894
衝動的に MP に置き換えてみたが、面白くなかった。

struct foo {
 typedef int type;
};

typedef foo::type t;
t n = 0;
cout << n << endl;
897デフォルトの名無しさん:2006/04/18(火) 11:46:21
#include <iostream>
#include <memory>

class FooType {
public:
 virtual void run() = 0;

protected:
 template <typename type> static void body() {
  type n = 0;
  std::cout << n << std::endl;
 }
};

template <typename type> class FooTypeRet : public FooType {
public:
 virtual void run() {
  body<type>();
 }
};

std::auto_ptr<FooType> foo() {
 std::auto_ptr<FooType> type(new FooTypeRet<int>);
 return type;
}

int main() {
 std::auto_ptr<FooType> type = foo();
 type->run();
}

近いと言えば近いのかもしれないコード。
898デフォルトの名無しさん:2006/04/18(火) 12:30:45
VC++6でSHORT型の配列1000個を持っているクラスのインスタンスを1ギガ分くらい確保したいのですが、何故か動きません。
*P=NEW CLASS1[500000]

2*30000 600MBなら取れるのですがそれ以上になると落ちます。

助けてください
899デフォルトの名無しさん:2006/04/18(火) 12:50:41
C++標準にSHORTやNEWなんてのはありません。
スレ違い。
900デフォルトの名無しさん:2006/04/18(火) 12:57:15
shortとnewは標準C++規約じゃなかったんですね。
901デフォルトの名無しさん:2006/04/18(火) 12:59:57
>>900 キーワードは case sensitive です。
902デフォルトの名無しさん:2006/04/18(火) 13:10:23
自分で解決してみます。携帯なんでめんどい
903デフォルトの名無しさん:2006/04/18(火) 13:36:30
アセンブラ部分に別変数を噛ませたら解決しました
904デフォルトの名無しさん:2006/04/18(火) 14:28:19
最後までスレ違いには気付かないわけだな
905デフォルトの名無しさん:2006/04/18(火) 15:18:44
PentiumDのマシンを買うことを検討しているのですが
gccなどで、両方のコアに計算させたいと考えています。

コンパイラオプションなどで簡単に処理を分散させることはできるでしょうか?
あるいは、それぞれのコアに分担を割り振る命令がC++のコードレベルで必須と
なるでしょうか。

よろしくお願いします。
906デフォルトの名無しさん:2006/04/18(火) 15:45:17
スレッド分ければ勝手にやってくれるんじゃね?

ちなみにオレはデュアルコアが欲しくて仕方ないんだが、
あと半年なんとか我慢して待つつもり。
907デフォルトの名無しさん:2006/04/18(火) 16:21:06
漏れは Vista SP1 待ち。
あと2年はあたらしいPC買えそうにもない
908905:2006/04/18(火) 16:43:42
>>906
ttp://www1.jp.dell.com/content/topics/segtopic.aspx/misc/dm/wb2_landing?c=jp&l=jp&s=bsd&~tab=3
> PentiumD 820 (2.80GHz)
> 512MBメモリ
> 80GB HDD
送料込みで29980円なので、やすいかなと思い検討しています。

単純だけれど、とてもでかい配列の計算です。
なるべくスレッドを分けたりしたくないのですが、やはり難しいでしょうか。

或いはこの用途では
PentiumD 820 (2.80GHz)は
Pentium4 521(2.80GHz)に比較し殆どアドバンテージがないと考えてよいでしょうか?
909デフォルトの名無しさん:2006/04/18(火) 16:45:30
>>905
>コンパイラオプションなどで簡単に処理を分散させることはできるでしょうか?
>あるいは、それぞれのコアに分担を割り振る命令がC++のコードレベルで必須と
>なるでしょうか。
後者
マルチスレッド
マルチプロセス
あたりがキーワード
910905:2006/04/18(火) 16:53:48
>>909
後者とのこと
ありがとうございます。
キーワード含め、もう少し調べてみます。
911905:2006/04/18(火) 17:15:23
http://jp.xlsoft.com/documents/intel/compiler/525J-001.pdf
のpage10 
5.1.自動並列化
のあたりを読むと、コンパイラオプション(linuxの場合、-parallel指定)にて
並列化される可能性があることがわかりました。

自動並列化により、ループ内の処理がコード的に分割される様子もわかりました。
gccで対応しているかわかりませんが、可能性があることがわかりました。
912デフォルトの名無しさん:2006/04/18(火) 17:35:59
無料かつOpenMPで並列化するのならWindows環境だとVC++2005Expressが一番楽だぞ。
LinuxならICCが無料で使える。gompは・・・まあ、ね。
913905:2006/04/18(火) 18:29:54
>>912
ありがとうございます。
ICCいいですね。

あと
GCCも4.2でOpenMP対応するとの説もあるようで、先が楽しみです。

みなさま、ありがとうございました。
914デフォルトの名無しさん:2006/04/18(火) 20:43:03
>>898
VC6 やとデフォで nothrow ちゃうか?
915デフォルトの名無しさん:2006/04/18(火) 20:44:38
>>905
CPU アフィニティは OS のシステムコールで制御するものなんで
このスレで話せることは少なそうだな
916デフォルトの名無しさん:2006/04/19(水) 00:24:01
>>905
PentiumDは爆熱騒音の原因になる地雷CPU。
急ぎじゃなければ7月以降に出る予定になっているConroeコアのCPU、
が搭載されたPCにした方がいいと思うぞ。

まぁ、発売時期が明確になっていないのが難点だが。

■Quake 4で1.5倍,F.E.A.R.で1.7倍!?Pentium Dより圧倒的に高速なConroe
ttp://www.4gamer.net/news/history/2006.04/20060406232305detail.html
917833:2006/04/19(水) 01:07:16
6/7日発売だよ焜炉
自作板の情報だからまぁほぼ確定だと思うよ
918デフォルトの名無しさん:2006/04/19(水) 01:15:25
template <class T>
class Hoge : Hogehoge<T> {
    ...
};
このようなクラスがあったとき、Hoge のコンストラクタのイニシャライザで
@Hoge(int x) : Hogehoge(x) { ... }
AHoge(int x) : Hogehoge<T>(x) { ... }
とするのではどちらが正しいのですか?
VC8では両方、g++3.4ではAがコンパイル通ったのですが
919デフォルトの名無しさん:2006/04/19(水) 01:27:52
A
920デフォルトの名無しさん:2006/04/19(水) 03:36:22
namespace LLNN = LongLongNamespaceName;
上の様な分って重なっても大丈夫なのでしょうか?
例えば、
a.h
namespace LongLongNamespaceName {ほげ}
namespace LLNN = LongLongNamespaceName;

b.h
#include "a.h"
namespace LongLongNamespaceName {はげ}
namespace LLNN = LongLongNamespaceName;
上の場合、b.hでnamespace LLNN = LongLongNamespaceName;の部分がa.hのそれと
ダブってしまうと思うのですが
921デフォルトの名無しさん:2006/04/19(水) 03:48:51
いいよ。
っていうか試してみたらすぐ分かると思うが
922デフォルトの名無しさん:2006/04/19(水) 19:04:00
template <class T>
class C {
public:
    T& getT() { return t_; }
private:
    T t_;
};
template <class T>
class D : public C<T> {
public:
    T& f() { return getT(); }
};
上記のコードをg++3.2でコンパイルしたところ、
Main.cpp: In member function `T& D<T>::f()':
Main.cpp:11: error: there are no arguments to `getT' that depend on a template parameter, so a declaration of `getT' must be available
Main.cpp:11: error: (if you use `-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)
とエラーが出ました。私にはどこも間違っているように見えないのですが、これはg++のバグでしょうか?
それとも上記のコードにどこか間違いがあるのでしょうか?
923デフォルトの名無しさん:2006/04/19(水) 19:12:43
>>922
Dの基底であるC<T>はテンプレート引数であるTに依存しているから
Dのコンパイル時点では型が確定していないのでgetTを持つかどうかが不明。よってエラー。
ってことらしい。
924デフォルトの名無しさん:2006/04/19(水) 19:19:09
>>922
言い忘れた。
this->getT()やC<T>::getT()と明示的に呼ぶか
適当な所でusing C<T>::getT;を入れればOKっぽい。
925デフォルトの名無しさん:2006/04/19(水) 19:40:29
>>924
ありがとうございます
教えていただいた方法で問題は解決出来たのですが、
>Dのコンパイル時点では型が確定していないのでgetTを持つかどうかが不明。
というのがよく理解できませんでした。
Tの如何に関わらず、C<T>はgetTを持つので、C<T>からpublicに派生する
Dも当然getTを持つと思うのですが・・
926デフォルトの名無しさん:2006/04/19(水) 19:50:15
>>925
テンプレートの解釈は、二段階の名前解決をふむ。
最初は、Nondependentな名前のみが解決され、
インスタンス化されるときに、Dependetな名前が解決される。
Two-Phase Lookupという。
Dependentは、簡単に言うとテンプレートがかかわるもの。

たとえば、グローバルにgetT()という関数があったらどうなる?
当然、こっちのほうを呼び出すべき。
VCとかは、インスタンス化されるときに、すべての名前を解決するから、
>>922のようなコードでも、問題なく通ってしまう。

927デフォルトの名無しさん:2006/04/19(水) 19:51:51
>>925
この説明がわかりやすいかな。

ttp://www.codeproject.com/cpp/TwoPhaseLookup.asp
928デフォルトの名無しさん:2006/04/20(木) 09:27:44
Win32 APIでよくあるA/Wを吸収するマクロは型の場合、typedefでも代用できますか?

#ifdef UNICODE
typedef CHogeA CHoge;
#else
typedef CHogeW CHoge;
#endif
929デフォルトの名無しさん:2006/04/20(木) 09:39:32
>>928
可能、というよりWinAPIでもTCHAR型は

#ifdef _UNICODE
typedef wchar_t TCHAR;
#else
typedef char TCHAR;
#endif

となっているはず
930デフォルトの名無しさん:2006/04/20(木) 09:50:25
>>929
どうも有り難うございます。
てっきり#defineだけかと思ってました。
931デフォルトの名無しさん:2006/04/20(木) 15:25:14
A/Wの区別って、引数リストで区別できないの?
932デフォルトの名無しさん:2006/04/20(木) 15:42:53
>>931
APIはC++だけのものじゃないので無理。
933デフォルトの名無しさん:2006/04/20(木) 15:52:38
boost::ptr_vectorには何故resizeが無いのでしょうか?
934デフォルトの名無しさん:2006/04/20(木) 15:55:24
>>933
つ[boostスレ]
935デフォルトの名無しさん:2006/04/20(木) 18:38:17
>>931
GetWindowTextA/Wのように引数や戻り値まで全く同じものがある。
それでもC++ならテンプレートの特殊化でどうにかできるけれどさ。
936デフォルトの名無しさん:2006/04/20(木) 18:54:06
C++のオーバーロードでは、GetCommandLineは区別できないな
937デフォルトの名無しさん:2006/04/20(木) 20:04:57
ファイルの文字を一文字ずつ取得したくて
while (!ifstr.eor()) { // ifstr = ifstream
char ch;
ifstr >> ch;
cout << ch;
}
と書いたのですが、何故か改行が表示されなかったので、今度は
while (!ifstr.eor() {
std::cout << (char)ifstr.get();
}
としたら今度は一番最後に変な文字(見たところ値は-1のようです)が表示されるようになりました。
どうすれば私のしたいことが出来るようになるのか教えてください
938デフォルトの名無しさん:2006/04/20(木) 20:19:09
とりあえず、chはループの外で宣言な。
939デフォルトの名無しさん:2006/04/20(木) 20:22:37
getして
初めて気づく
俺EOF
940デフォルトの名無しさん:2006/04/20(木) 21:30:14
エオフ
941デフォルトの名無しさん:2006/04/20(木) 21:37:09
独習C++という本の12章の理解度チェックの問題4
の解答をコンパイルしてみたらエラーで動きません。
警告も出ています。

警告の内容は以下のとおりです
c:\一鉄\趣味\ゲーム作成\勉強\TeachYourselfC++\12-check-4.cpp(45) : warning C4541: 'typeid' が /GR- を使用したポリモーフィック型 'A' で使用されています; 動作結果は保証されません。
c:\一鉄\趣味\ゲーム作成\勉強\TeachYourselfC++\12-check-4.cpp(47) : (省略)
c:\一鉄\趣味\ゲーム作成\勉強\TeachYourselfC++\12-check-4.cpp(49) : (省略)

警告だけで、エラーではないのでコンパイルは出来ます。
ですが実行時になってからエラーが表示されます
それの内容は
This Application has requested the Runtime to terminate it in an unsual way.
Please contact the application's support tema for more information.

です。
いろいろためしてみると
myclassというクラスとそのクラス型のobjというオブジェクトがあったとすると
typeid(obj)は機能するのですが
typeid(myclass)は機能しません。

だれかどうすればいいか分かる方はいませんか?
長々とすいませんですた
942デフォルトの名無しさん:2006/04/20(木) 21:43:37
>>941
コンパイラによっては、RTIIを使う際コンパイラオプションで
RTIIを使うことを指定しないといけないことがある。
943デフォルトの名無しさん:2006/04/20(木) 21:44:09
一鉄w
944デフォルトの名無しさん:2006/04/20(木) 21:50:12
一鉄打ち込んだソースみせてくれよ
945デフォルトの名無しさん:2006/04/20(木) 21:57:40
>>942
細かいことなんだが、実行時型情報はRTTIじゃなかったか?
946デフォルトの名無しさん:2006/04/20(木) 22:50:13
run time type informations
947デフォルトの名無しさん:2006/04/20(木) 23:30:33
>>943-944
orzOLT
948デフォルトの名無しさん:2006/04/20(木) 23:31:21
>>942
どうもです^^
949デフォルトの名無しさん:2006/04/21(金) 04:41:40
run time type identification?
950デフォルトの名無しさん:2006/04/21(金) 07:20:35
information
951デフォルトの名無しさん:2006/04/21(金) 09:48:04
string型に格納されている文字列の
一番最後の文字を取るにはどうすれば良いですか?
vectorとかならback()で取れるんですが・・
952デフォルトの名無しさん:2006/04/21(金) 10:10:12
*str.rbegin()
str[str.size() - 1]
*(str.begin() + str.size() - 1)
*(--str.end())
953デフォルトの名無しさん:2006/04/21(金) 11:28:20
954デフォルトの名無しさん:2006/04/21(金) 13:06:18
>>938
えっ!?
955デフォルトの名無しさん:2006/04/21(金) 13:07:07
そろそろ次スレ。
テンプレにある cuj のリンクどうする?
956デフォルトの名無しさん:2006/04/21(金) 16:18:45
>>953
>OK, we all know std::basic_string is bloated and already has way too many members.
書き出しがこれかよwww
957デフォルトの名無しさん:2006/04/21(金) 17:50:02
C++98→C++03の変更は細かい修正だけと聞いていますが、
その差分だけまとめた文書はないでしょうか?
双方もっているのですが、自分で調べるのは大変なので。
958デフォルトの名無しさん:2006/04/21(金) 23:13:36
http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html

のページで "Status: TC" という語で検索する
959957:2006/04/22(土) 09:01:55
ありがトン
960デフォルトの名無しさん:2006/04/23(日) 12:10:55
あふぉぢゃねーの
961デフォルトの名無しさん:2006/04/25(火) 14:09:13
fread(3)とかの3って引数の数?manの3?
どっちが一般的?
962デフォルトの名無しさん:2006/04/25(火) 14:19:00
manの3。ライブラリだぜということ。UNIX以外では意味ない。
引数の数で使うことはない。
それからスレ違い。
963デフォルトの名無しさん:2006/04/25(火) 16:47:17
std::vectorやstd::map等のコンテナについてなんですが
begin(), end()や、イテレータの代入・インクリメント・デクリメント等の操作で
例外がthrowされる可能性はあるんでしょうか?
964デフォルトの名無しさん:2006/04/25(火) 16:51:43
begin() end() それぞれの operator についてソースを読めば?
965デフォルトの名無しさん:2006/04/25(火) 16:53:00
いや、実装依存の話じゃなく規格で定められているのかなと。
966デフォルトの名無しさん:2006/04/25(火) 17:54:09
それこそ規格書読めばという話になるが
967デフォルトの名無しさん:2006/04/25(火) 18:33:34
>>963
禿本Special Editionの付録Eを読んで。
今手元にないからアレだけど。
968デフォルトの名無しさん:2006/04/25(火) 18:55:46
規格書持ってないんで
ttp://www.kuzbass.ru/docs/isocpp/
ここで調べたけど書いてないみたい。
969デフォルトの名無しさん:2006/04/25(火) 19:03:13
強い保証と非送出保証が書かれてないものは規格的に未定義。
970デフォルトの名無しさん:2006/04/27(木) 14:44:11
ifstreamでテキストファイルを読み込む場合なんですが、
一度目は問題なく読み込めるんですが、
同じ作業中にもう一度同じファイルを読み込もうとした場合、
ちゃんと読み込めないことがあるんですが、どうなってるんでしょう?
971デフォルトの名無しさん:2006/04/27(木) 15:01:46
「ちゃんと読み込めない」を具体的に
972デフォルトの名無しさん:2006/04/27(木) 15:10:50
foo970(char *filename) {
  ifstream file1(filename);
   :
   :
  //←なぜかクローズしてない
  ifstream file2(filename);
  readline(line); // ちゃんと読み込めない
}
973970:2006/04/27(木) 15:10:56
ファイルのオープンはできてるんですが、
文字をどうも文字化けを起こした状態で読み込んでしまっているようです。
必ず起こるわけではなく、時折繰り返しているうちに起こります。
974970:2006/04/27(木) 15:12:57
クローズはきちんと行ってます。
975デフォルトの名無しさん:2006/04/27(木) 15:13:50
最初に開いたファイルに書き込みとかしてるの?
976970:2006/04/27(木) 15:14:12
書き込みはしてません。読み込むだけです。
977デフォルトの名無しさん:2006/04/27(木) 15:16:28
読めないファイルとコードを晒してくれたほうが早いな
978デフォルトの名無しさん:2006/04/27(木) 15:18:22
とりあえず、open出来たかどうかとか、読み込み成功したかとかは
is_open(), good()とかで確認してる?
979970:2006/04/27(木) 15:19:17
丸コピでスマソ。
fi.open(fileChar, ios::in | ios::binary);
if (fi){
while(charaNum < 100){
charaNum++;
fi.seekg(1, ios::cur);
}
fi.seekg(0, ios::beg);

while(!fi.eof()) //ファイルの最後にきたら終了
{
sprintf(cha2, "%s", cha1);
fi.read(cha1, 1);
sprintf(chan, "%s%s", cha2, cha1);
if (strcmp(chan, "le") == 0){//改行
strs.erase(strs.end() - 1);
strvec.push_back(new string(strs, 0, strs.size()));
strs = "";
fi.seekg(2, ios::cur);
}else{
strs.append(cha1);//文字を保存
}
}
fi.getline(chars, 255);
strvec.push_back(new string(chars));
}
fi.close();
980デフォルトの名無しさん:2006/04/27(木) 15:23:39
つバッファオーバーフロー
981デフォルトの名無しさん:2006/04/27(木) 15:31:04
初期化してないcha1の使いまわしでcha2が溢れてるだけじゃねーの?
982970:2006/04/27(木) 15:32:19
再度読み込む際は、これのあるオブジェクトごとdeleteしてるので、
バッファオーバーフローは無いと思うんですが。
一応格納する文字列のサイズは読み込む際は毎回0になってます。
983970:2006/04/27(木) 15:33:19
sprintf(cha1, "");
sprintf(cha2, "");
で一応初期化はしてます。
984デフォルトの名無しさん:2006/04/27(木) 15:33:33
chaではじまる変数の宣言と読み込もうとしたファイルのサイズも晒せ
985970:2006/04/27(木) 15:37:15
vector<string*> strvec;//ファイル内容行ごとに格納
string strs;//一行読み込み
int charaNum;//文字数
char cha;
char cha1[2];
char cha2[2];
char chan[4];
char fileChar[100];
ifstream fi;//ファイル入力
ファイルサイズは34.6kb〜65.9kbです。
986デフォルトの名無しさん:2006/04/27(木) 15:48:50
sprintf(cha1, "");がまずい

最初の一バイト目だけ'\0'で初期化されるけど、ニバイト目にはゴミが入ってる可能性がある。
fi.read(cha1, 1); で一バイト目に文字を入れたのはいいけど、ニバイト目に運良く'\0'が入っていれば次の
sprintf(chan, "%s%s", cha2, cha1); で期待通りの動作になる。

でも、ニバイト目に'\0'じゃないなにか ('A'とか)がはいってると
sprintf(chan, "%s%s", cha2, cha1); で readで読んだ一文字目 + 'A' + '\0'が現れるまで延々と続く
ゴミ文字列がchanにコピーされる

chanのサイズが4バイト分しかないんで、3文字+'\0'を越える長さの文字列を入れると悲しいことが起こる。

readした直後に cha1[1] = '\0';とかやっとけば問題ない

二文字目にたまたま何が入ってるかは、おまいのプログラムのつくりによるんだが
一回目は'\0'が入ってて、二回目以降は違うものが入ってるんだと思う
987970:2006/04/27(木) 16:09:04
ありがとうございました。
おかげ様で上手く行きそうです。
助かりました。
こんな落とし穴があったとは。
988デフォルトの名無しさん:2006/04/27(木) 17:57:09
std::ifstreamやofstreamなどのファイルストリームが
デストラクタで自動的にcloseされるようになっていない
のには何か理由があるのですか?
989デフォルトの名無しさん:2006/04/27(木) 20:24:00
>>988
デストラクタでcloseされるよ。
990デフォルトの名無しさん:2006/04/28(金) 01:13:15
>>970
最後まで読んでstd::ios::eofbitとかstd::ios::failbitが立ってしまってんだろ。

C++のファイルストリームは、Cとは違い、一度これらのフラグが立ったら、
自動ではクリアされない。そして、クリアしないと入出力が停止される。

clear()汁。
991デフォルトの名無しさん:2006/04/28(金) 07:47:59
俺の股間もよく failbit がたってしまいます。
clear() しても今度はすぐにストリームが空になって
eofbit たってしまいます。


992デフォルトの名無しさん:2006/04/28(金) 08:29:50
これだからスパゲティちんこは・・・
993デフォルトの名無しさん:2006/04/28(金) 08:32:04
>>991 は熱しやすく冷めやすい
994デフォルトの名無しさん:2006/04/28(金) 09:40:36
openできなくなるよりマシ
995デフォルトの名無しさん:2006/04/28(金) 09:45:58
(脳内)彼女のソケットも open できません。
996デフォルトの名無しさん:2006/04/28(金) 09:53:44
C++相談室 part49
http://pc8.2ch.net/test/read.cgi/tech/1146185570/

立てたから後頼む。俺ちょっと出かけるんで。すまん。
997デフォルトの名無しさん:2006/04/28(金) 10:04:30
STLつかうと一気に実行ファイルサイズが10倍に?!
998デフォルトの名無しさん:2006/04/28(金) 11:17:47
>>997
環境によるだろ。
俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力
ランタイムを使用するようにして使っているが、例えばstd::vectorを
使っても使わない時と比べ10Kほどしか増えない。
999デフォルトの名無しさん:2006/04/28(金) 11:20:19
すげえ!うむごくろう
1000デフォルトの名無しさん:2006/04/28(金) 11:24:39
1000
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。