C++相談室 part65

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

前スレ
C++相談室 part64
http://pc11.2ch.net/test/read.cgi/tech/1225542747/l50
2デフォルトの名無しさん:2008/12/27(土) 10:32:32
複数のcppで同じ文字配列を使いたくて、
ヘッダーファイルで extern vector<string> String(10);
cppファイルで vector<string> String(10);
としたのですが「'String' : 再定義されました」とエラーになりました。

どういう風にやれば良いのでしょうか。
3デフォルトの名無しさん:2008/12/27(土) 10:48:49
(10)がイケテナイ
4デフォルトの名無しさん:2008/12/27(土) 10:53:57
地鎮祭だ

STLつかうと一気に実行ファイルサイズが10倍に?!

環境によるだろ。
俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力
ランタイムを使用するようにして使っているが、例えばstd::vectorを
使っても使わない時と比べ10Kほどしか増えない

すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。

C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
とかいうエラーが出るんだけどこれってどうすればいいの?

#include <stdafx.h>
後死ね。

言葉が悪いな。それで教えているつもりか。
まぁヒントぐらいにはなったな。
うむごくろう。
5デフォルトの名無しさん:2008/12/27(土) 11:09:49
>>3
なるほど!配列数はヘッダで宣言しないのですね。
教えて下さり有難う御座いましたm(_ _)m
6デフォルトの名無しさん:2008/12/27(土) 14:08:11
そもそも、それ配列じゃねえし。
7デフォルトの名無しさん:2008/12/27(土) 14:52:20
>>5
いやもう少しわかりやすくいうと(10)ってstd::vectorのコンストラクタを
呼び出す構文なのね。つまり宣言ではなくて定義になる。
8デフォルトの名無しさん:2008/12/27(土) 17:19:10
実行速度を測るためのコードを書くと、最適化でコードがごっそり消されたり、
キャッシュのせいか2度目の実行時の速度がめちゃくちゃ速くなったりすることがよくあります。
どういうところを気をつければ、正しい実行速度が測れますか?
9デフォルトの名無しさん:2008/12/27(土) 17:30:37
>>8
測るためのコードを書かず、測りたいコードを素直に測る。
10デフォルトの名無しさん:2008/12/27(土) 18:02:43
>>9
ライブラリが提供する1つの機能(STLとか)の速度を測りたい時にそうもいかないです。
11デフォルトの名無しさん:2008/12/27(土) 18:04:31
>>10
測りたいコードについて、「1つの機能」だけを適用した状態にして測り、元のコードの
結果と比べればいい。
12デフォルトの名無しさん:2008/12/27(土) 18:50:33
>>10
あんまり意味がないぜそれ
実際のコードで図るしかない
だからみんな実測実測いってるわけだから
13デフォルトの名無しさん:2008/12/27(土) 18:52:00
そのノウハウだけで商売になりそうなくらい速度計測は難しい。
だが商売になりそうにないくらい需要は薄い。
14デフォルトの名無しさん:2008/12/27(土) 19:24:22
C++のオナニー機能を使うからそういう困ったことになる
C+クラスしか使わなければ素直にアセンブラで検討すればいいだけなのに
15デフォルトの名無しさん:2008/12/27(土) 19:31:45
またお前か。
16デフォルトの名無しさん:2008/12/27(土) 19:36:09
>>14
アセンブリコードから速度が検討できるのって、キャッシュや分岐予測のない環境だけだろ。

そう言うと「キャッシュや分岐予測なんて要らない」って言い出すんだろうけどな、あんたは。
17デフォルトの名無しさん:2008/12/27(土) 19:44:07
>>14
大丈夫、レガシーCのコードでも簡単に計測できないから。
もしできると思っているのなら、ソフトウェアだけでなくハードウェアの知識も10年くらい手前で止まっているという証明。
18デフォルトの名無しさん:2008/12/27(土) 19:44:45
いまどきアセンブラから速度ってw
19デフォルトの名無しさん:2008/12/27(土) 19:48:48
ナノ秒オーダーでタイミング取るために実際の正確なサイクル数が必要とかならともかく
二つの方法を比べてどっちが速いかならアセンブラで十分検討できるだろう
それすら出来なくしてくれるのがC++のオナニー機能どもだけど
20デフォルトの名無しさん:2008/12/27(土) 19:53:00
あんた、おつむの更新を10年くらい忘れてないか?
そう簡単に事が進まないのが今時のCPUだ。

まぁ、未だにシングルタスクOSで頑張っているなら気にすることもないかも知れんが。
21デフォルトの名無しさん:2008/12/27(土) 19:53:52
>>11-13
例えばコンテナに対する操作にしても、一概にこれといった速度を計測できないわけですか。
googleで検索しても、この手の情報がほとんど出てこないのも納得しました。
22デフォルトの名無しさん:2008/12/27(土) 20:01:18
>>21 単品で計測はできるんだろうけど、それじゃあんまり意味は無いってこと。
23デフォルトの名無しさん:2008/12/27(土) 20:02:01
どうやら検索の仕方も10年前で止まっているらしい。決して少なくない情報さえ見つけられないのだから。
24デフォルトの名無しさん:2008/12/27(土) 21:02:41
>>22
すみません、単品の計測にあまり意味がないのはどうしてですか?
>>23
ttp://www.codeproject.com/KB/stl/vector_vs_deque.aspx
例えばSTLの速度だと、STLスレで紹介されてたここぐらいしか知らないんですが、他に知っていたら教えて欲しいです。
25デフォルトの名無しさん:2008/12/27(土) 21:09:06
>>24
処理によって全然違うから
26デフォルトの名無しさん:2008/12/27(土) 21:16:27
>>25
前後の処理によって速度が変わってくるということでしょうか?
27デフォルトの名無しさん:2008/12/27(土) 21:38:24
抽象的な一般論で良ければ、
vectorのinsertはO(n)だけど、setのinsertはO(log n)であるというような計算量の規定はあるよ。
28デフォルトの名無しさん:2008/12/27(土) 21:55:51
>>26
それもあるかもね
とにかく影響するもんが多すぎて調べられない
考えてるほど単純じゃないよ
29デフォルトの名無しさん:2008/12/27(土) 22:51:21
C++は頼みもしないおかしなものを大量にくっつけるからねぇ…
30デフォルトの名無しさん:2008/12/27(土) 23:05:46
>>27
大体はそれで間に合うんですが、実際の細かい速度の差が気になりました。
>>28
複雑なんですね。

thxでした。
31デフォルトの名無しさん:2008/12/28(日) 17:40:48
class Hoge {...};

class Fuga {
  Hoge hoge_;
  ...
};

class Piyo {
  vector<Fuga> fugas_;
  ...
};

Fuga1つに対して必ずHoge1つが必要なので、HogeをFugaのメンバにしたのですが、
よく考えたらFugaの中でHogeは使われておらず、getter/setterがあるのみです。
FugaのメンバからHogeをなくして、Piyoのメンバにvector<Hoge> hoges_;と書くべきなのでしょうか?
32デフォルトの名無しさん:2008/12/28(日) 17:52:34
>>31
Hogeにはgetter/setterのみということは、PiyoはHogeについても一一管理しているのか?
それならばその考え(Fugaのメンバにしない)でもいいと思うが、Hogeのレゾンデートルに
Fugaの存在が不可欠ならPiyoに対してFugaを公開すること自体がおかしい気もする。
33デフォルトの名無しさん:2008/12/28(日) 18:21:20
>>32
Hogeのメソッドは全て、Piyoが必要とするもの、といった感じです。
HogeはFugaを構成する1つの部品という見方で、Fugaのメンバにしていましたが、Hoge単体で見ても意味のあるオブジェクトではあります。

> Piyoに対してFugaを公開すること自体がおかしい気もする。
すみません意味が分からないんですが、単にFugaとHogeの打ち間違えでしょうか?
34デフォルトの名無しさん:2008/12/28(日) 18:30:27
>すみません意味が分からないんですが、単にFugaとHogeの打ち間違えでしょうか?
あ、悪い、混乱してた。その通りで。Hoge自体に意味があるならFugaが関与する必要もない気がするけど、
常にセットで扱うならセットにしておきたい気もするし、悩みどころだな。
35デフォルトの名無しさん:2008/12/28(日) 19:26:03
セットで扱いたいならvector<pair<Fuga,Hoge> >で持っとくとか

でもFugaとHogeって実は何の関係もないんじゃね?
36デフォルトの名無しさん:2008/12/28(日) 21:27:29
>>34
うーん、悩みますねぇ・・・。

>>35
pairはfirst,secondが何を指しているかわかりづらいのがちょっと嫌なんですよね。
クラスとクラスが関係するとはどういうことなのかわからなくなってきました。
37デフォルトの名無しさん:2008/12/28(日) 21:35:02
>>36
pair の first, second がいやなら自分で構造体(クラス)を作れば良いじゃない。
38デフォルトの名無しさん:2008/12/28(日) 21:57:06
>>37
たしかにそうですね。
39デフォルトの名無しさん:2008/12/28(日) 22:19:40
boost::tupleはどうするんだ
もっとひでえぞ
40デフォルトの名無しさん:2008/12/28(日) 22:20:13
あ、今じゃstdext::tr1::tupleか
41デフォルトの名無しさん:2008/12/29(月) 11:42:17
ぽまえら、C++でfinally的なものを使ってる輩はいるかにょ?
「class finallyを作って、デストラクタにやりたい処理を入れる」は
ぽもろ〜なアイデアと思ったのであるが、実際使ってみると
関数とスコープが違う為に、いまいちつかえなりかずき。
よろしく教えてごモンキ〜
42デフォルトの名無しさん:2008/12/29(月) 13:24:48
俺はfinallyの必要性感じた事ないな。
後始末が必要なもんはカプセル化して、デストラクタに任せてる。
43デフォルトの名無しさん:2008/12/29(月) 14:22:20
finallyは結局デストラクタをインラインで書いてるようなもんだから
RAIIができるC++にはあんまり必要ない
逆に言えばJavaにfinallyが必要なのはデストラクタがないから
44デフォルトの名無しさん:2008/12/29(月) 15:28:15
いちいちクラス書くのめんどい場合もあるけどな
45デフォルトの名無しさん:2008/12/29(月) 16:53:31
RAII 使ってると大抵の場合は finally とか必要にならない。
たまに欲しくはなるが。
46デフォルトの名無しさん:2008/12/30(火) 16:01:09
クラスの継承とアドレスに関して質問です。
たまに、派生クラスのインスタンスのポインタを基底クラスのポインタに入れたり、void*にいれておくと
単純なキャストでは基底クラスの純粋仮想関数が呼ばれたりすることがありますが、そうなる条件というのはどういう時ですか?
47デフォルトの名無しさん:2008/12/30(火) 16:11:29
>>46
そうなる場合が思いつかないな?そうなる場合のソースプリーズ

48デフォルトの名無しさん:2008/12/30(火) 16:33:35
多重継承がないなら本当にアホなことをしていると思われる
49デフォルトの名無しさん:2008/12/30(火) 16:40:24
なぜ、void*な変数にいれるんだ?
50デフォルトの名無しさん:2008/12/30(火) 16:41:19
void*はかなり怪しいな。
慎重にDerived*→void*→Derived*としているなら問題ないはずだが、
例えば、Derived*→void*→Base*とかはまずいだろう。
51デフォルトの名無しさん:2008/12/30(火) 17:01:13
>>49 APIを通さなくてはならないからです。
>>50 とりあえず
52デフォルトの名無しさん:2008/12/30(火) 20:51:17
アップキャストは単なるアドレスの解釈の変更ってだけじゃないことがあるので
void* を通す時は必ず void* を通す前の型に戻す必要がある。
53デフォルトの名無しさん:2008/12/30(火) 21:01:25
近頃思うんですが、あるデータとそれに対する操作を実装するとき、
data.F()という実装より、F(data)という実装の方が、
操作の拡張がしやすい気がします(前者はData.hを書き換えないといけないし、メンバ関数が増えていくのも嫌)。
あと、2種類のデータに対する操作を実装する時に、getter/setterだらけになるのもちょっと・・。
OOPに対する理解が足りてないだけなのでしょうか?それとも別のプログラミングパラダイムで書くべき物なのでしょうか?
54デフォルトの名無しさん:2008/12/30(火) 21:05:56
dataの公開インターフェースだけで実装できる機能だったら、
F(data)の方がカプセル化という観点ではオススメと
EffectiveC++に書いてあったような

つまりstd::stringのメンバ関数とかダメじゃねと
55デフォルトの名無しさん:2008/12/30(火) 21:06:22
>>53
パラダイムの問題というよりは、たぶんC++のシンタックスが古臭いのが原因だと思うよ。
新しく出来てきたオブジェクト指向言語は、どっちの問題もシンタックスシュガーで解決してる。
56デフォルトの名無しさん:2008/12/30(火) 21:12:34
D とか F(data) って関数を data.F() って呼べた気がする。
57デフォルトの名無しさん:2008/12/30(火) 21:17:51
ジェネリック関数ってやつか
58デフォルトの名無しさん:2008/12/30(火) 21:18:23
>>57
エクステンションメソッドです…
59デフォルトの名無しさん:2008/12/30(火) 21:44:27
C++に近い言語での拡張メソッドはC#だけだと思っていた。
60デフォルトの名無しさん:2008/12/30(火) 21:47:11
>>53
操作を拡張するときは継承を使う。そうすると既存クラスのヘッダーは変更せずにdata.F()を追加できる。
メンバ関数が増えそうなら、継承の階層を分けてメンバ関数を分類すればいいと思う。
F(data)も一応隠蔽の役目を果たすのでありだと思うが、無造作に作りすぎるとわけがわからなくなると思う。

メンバ変数に単純にアクセスするためのgetter/setterが増えると隠蔽するという考え方が崩れていくので要注意。機能を整理して最小限のメンバ関数を作るように検討したほうがいいと思うよ。

61デフォルトの名無しさん:2008/12/30(火) 21:49:44
機能拡張で安易に継承を使うのはどうかと思うよ。
継承したクラスを通さないと追加した機能を実現できないってのは、
複数の機能を別々のタイミングで追加したい場合に問題になる。
62デフォルトの名無しさん:2008/12/30(火) 21:55:28
vectorなんかの継承と同じことだな。
デストラクタにvirtualが付いていても、メンバ変数の追加が無くてもだ。
スライシングは動いても気持ち悪いし、既存ライブラリから
引数を与えられる場合に対処できない(まさか無理にダウンキャストしないよな?)し。
63デフォルトの名無しさん:2008/12/30(火) 21:59:44
>>54
なるほど、publicメンバだけで実装できる場合に非メンバ関数で実装することはよくあるんですね。
しかし、privateメンバにはアクセスできないので、Dataをクラスで書くことによって拡張がしにくくなるのでは?と思ってしまいます。
>>53にも書きましたが、void F(DataA& dataA, DataB& dataB)という関数を書く時とか特に。

>>55,56
そういう書き方ができると便利ですね。
C++0xで使えるようになっていて欲しい。

>>60
インターフェイス以外の継承には抵抗があります。
継承で拡張するときのために、常にメンバ変数をprotectedに書いておくというのもちょっと。
64デフォルトの名無しさん:2008/12/30(火) 22:04:24
継承するときでもメンバー変数はprivateにしたほうがいいよ。
65デフォルトの名無しさん:2008/12/30(火) 22:06:48
なんで?
66デフォルトの名無しさん:2008/12/30(火) 22:14:13
public にしない方がいいのと同じ理由。
でも、実際には面倒くさいので(ry
67デフォルトの名無しさん:2008/12/30(火) 22:16:13
template<class T>friend class T;
これってどういう意味ですか?
68デフォルトの名無しさん:2008/12/30(火) 22:22:56
コンパイルエラー
69デフォルトの名無しさん:2008/12/30(火) 22:24:57
>>67 >>68
C++0x からできるかも
70デフォルトの名無しさん:2008/12/30(火) 22:32:29
これが通るBCCはおかしいのかな
71デフォルトの名無しさん:2008/12/30(火) 22:36:38
それより意味を教えてください!
72デフォルトの名無しさん:2008/12/30(火) 22:38:47
>>71
まんま
73デフォルトの名無しさん:2008/12/30(火) 22:55:17
struct Base{
  virtual ~Base(){}
  virtual void func() = 0;
};
struct Middle1:public virtual Base{
  virtual ~Middle1(){}
  void func(){}
};
struct Middle2:public virtual Base{
  virtual ~Middle2(){}
  void func(){}
};
struct Derived:public Middle1,public Middle2{
};
ダイアモンド継承で更に曖昧なオーバーライドを解消したい場合はどうすれば良いですか・・・
74デフォルトの名無しさん:2008/12/30(火) 22:57:18
Derived でも func を定義する。
75デフォルトの名無しさん:2008/12/30(火) 23:06:03
Middle1とMiddle2両方でfuncの実装は必要です。Derivedで定義しちゃったら、両方無効ですよね?
76デフォルトの名無しさん:2008/12/30(火) 23:08:51
関数名を同じにしていることの意図によるだろ
あるいは安直すぎる関数名で事故ったのかは計り知れんが
77デフォルトの名無しさん:2008/12/30(火) 23:09:29
Derived を Middle1 にキャストしても
仮想関数である以上 Derived の func が呼ばれる。
現状では Derived には func が2つあるので
何を呼んでいいか分からないのでエラーになる。
だから Derived に func を定義する必要がある。
中身は Middle1::func(); Middle2::func(); でいいかどうかは
Middle1::func() と Middle2::func() の実装による。
78デフォルトの名無しさん:2008/12/30(火) 23:11:33
そもそも func は Base で定義すべきものかも考えた方が良い。
istream と ostream でも seek 関数は seekg と seekp に分けている。
79デフォルトの名無しさん:2008/12/30(火) 23:20:05
Baseから派生クラスのfuncを呼び出し、更にそれぞれのfuncからMiddle〜の仮想関数を呼び出します。
DerivedにはMiddle1,Middle2が持つ仮想関数のオーバーライドがあるという形です。
こうすれば、リスナーの形をとりやすかったんですが・・・
80デフォルトの名無しさん:2008/12/30(火) 23:34:59
Derived のインスタンス d を
Middle1* にアップキャストしようが
Middle2* にアップキャストしようが
Base* にアップキャストしようが
p->func() として呼ばれるのは Derived::func() だ。
81デフォルトの名無しさん:2008/12/30(火) 23:48:18
割り込む形での質問になり申し訳ありません。
また、ひょっとしたらスレ違いかもしれません。。。

>>> tmp.cpp
#include <cstdio>

template <typename _T,int _N=2*1024*1024>
struct hoge{
  _T buf[_N];
};

int main(void){
using namespace std;
  typedef hoge<char> hage;
  hage h;
  h.buf[0] = 'a';
  printf("%d\n",(int)sizeof(hage));
  return 0;
}

> g++ tmp.cpp -O3 -Wall
> ls -s
12 a.out* 8 tmp.cpp

今までずっと「実行バイナリをメモリにロードするというのは、そのままメモリ上にコピーすること」と思いこんでいたのですが、
どうやら勘違いだったようです。
2Mのバッファは、いつどのタイミングでどこに確保されるのでしょうか。
82デフォルトの名無しさん:2008/12/30(火) 23:52:48
結局確保せずにおわると思うよw
83デフォルトの名無しさん:2008/12/31(水) 00:08:37
今試しにバッファサイズを32Mにしたらセグメンテーションフォルトになっちゃいました。
メモリはギガ単位で積んであるマシンなんですが……

>>82
えーそんなー(´・ω・`)
えっと、なぜでしょうか。
84デフォルトの名無しさん:2008/12/31(水) 00:11:22
それはたぶんスタックオーバーフローという奴かと
85デフォルトの名無しさん:2008/12/31(水) 00:13:12
そのバッファーはスタック上に取られている。バッファーの確保はnewを使う
86デフォルトの名無しさん:2008/12/31(水) 00:14:33
>>83
実行サイズが2Mがないことが疑問なんだよな?

2Mの確保は実行時に確保される
スタック足りるかは別として
87デフォルトの名無しさん:2008/12/31(水) 00:15:59
ulimit -a [~]
-t: cpu time (seconds) unlimited
-f: file size (blocks) unlimited
-d: data seg size (kbytes) unlimited
-s: stack size (kbytes) 8192
-c: core file size (blocks) 0
-m: resident set size (kbytes) unlimited
-u: processes 16383
-n: file descriptors 1024
-l: locked-in-memory size (kb) 64
-v: address space (kb) unlimited
-x: file locks unlimited
-i: pending signals 16383
-q: bytes in POSIX msg queues 819200
-e: max nice 0
-r: max rt priority 0

俺のスタックの設定はデフォルトです…。
88デフォルトの名無しさん:2008/12/31(水) 00:22:39
なるほど、スタックに積む段階で領域が確保される、と。
そして、スタックも32M無いからセグメンテーション違反が起きたと。
なんとなく理解できた気がします。
素直にnewしてコピー禁止してデストラクタでdeleteします。
ありがとうございました。

> ulimit
ulimit: command not found
(´・ω・`)ごめんなさい
89デフォルトの名無しさん:2008/12/31(水) 00:23:10
こうすれば、と書こうとしたが、funcはBaseからの仮想関数なのね、ならだめだ。
struct DM1 : public Middle1 {
virtual void func() {func_m1();}
virtual void func_m1() = 0;
};
struct DM2 : public Middle2 {
virtual void func() {func_m2();}
virtual void func_m2() = 0;
};
struct Derived : public DM1, public DM2 {
virtual void func_m1() {}
virtual void func_m2() {}
};
90デフォルトの名無しさん:2008/12/31(水) 00:24:27
hage自体をnewすればいいじゃん
91デフォルトの名無しさん:2008/12/31(水) 00:29:02
誰か AA 作ってよ
9273:2008/12/31(水) 00:30:46
>>89ありがとうございます。
ちょっと長くなりましたが、これでやりたいことできました。
仮想継承はむしろまずかったですね。
struct Base{
  virtual ~Base(){}
  void run(int i){func(i);}
  virtual void func() = 0;
};
struct Hoge:public Base{
  virtual ~Hoge(){}
  void func(int i){if(i>0&&i<10)hoge();}
  virtual void hoge() = 0;
};
struct Fuga:public Base{
  virtual ~Fuga(){}
  void func(int i){if(i>20)fuga();}
  virtual void fuga() = 0;
};
vector<Base*> container;
struct Derived:public Hoge,public Fuga{
  Derived(){
    container.push_back((Hoge*)this);
    container.push_back((Fuga*)this);
    container[0].run(5);
    container[0].run(15);
    container[1].run(25);
  }
  void hoge(){cout << "hoge()" << endl;}
  void fuga(){cout << "fuga()" << endl;}
};
93デフォルトの名無しさん:2008/12/31(水) 00:35:37
おっと・・・ちょっとミスった・・・。
9453=63:2008/12/31(水) 13:36:36
度々申し訳ないですが、もう少し質問を続けさせて下さい。

メンバ変数をprivateに置き、外部から操作する時はpublicメンバ関数を呼び出すことによって、カプセル化されますよね。
この利点はよく分かるのですが、あとで拡張するときにpublicメンバでできることしかできなくなるのが不便に感じます。

C++には、意味があってつけた制限をあとから明示的に解除する仕組みを持った物がありますよね。
const_castとか、boost::shared_ptrがT*への暗黙の型変換はないけどget()で取得できるところとか。
privateメンバに関しても、基本的には制限したいけど、明示的に制限を解除する仕組みが欲しくなります。
1つ方法としてfriendがありますが、あとで拡張したくなったときにpublicメンバだけじゃ無理!というケースで元のクラスをいじらず拡張することができません。

あとで拡張するときに、privateメンバへのアクセスできないことが問題になった場合、どのように解決すればよいのでしょうか?
95デフォルトの名無しさん:2008/12/31(水) 13:47:57
get()とset()を両方実装しておけば基本的にはそう言う問題は起きない気がするんだけど。
96デフォルトの名無しさん:2008/12/31(水) 13:55:51
>>94
あらかじめ共通の操作を行うメンバ関数をprotectedで用意しておく。
97デフォルトの名無しさん:2008/12/31(水) 13:59:54
クラス作った人が意図してないのに勝手に書き換えられたらprivateの意味が無い
98デフォルトの名無しさん:2008/12/31(水) 14:42:20
>>95
全てのメンバ変数にget()とset()を定義するぐらいなら、OOPやめて構造体+非メンバ関数で書いた方がいい気がしてきます。

>>96,97
当初の予定にないことを、あとで拡張したいと思うこと自体が間違ってるんですかねぇ・・。
99デフォルトの名無しさん:2008/12/31(水) 15:00:41
privateは駄目だろう
private属性の要素を見直したいなら作り直せ、は
それはそれで理にかなっていると思うが

COMみたいに実装とインターフェイスを分離する方法もあるが。。
100デフォルトの名無しさん:2008/12/31(水) 15:09:57
>>98
カプセル化ってそういうもんだろ。

内部実装に不用意に馴れ馴れしくすると、
もはやカプセル化の意味がない。

publicでゲッタとセッタがあっても、
裏にprivateなフィールドが存在するとは限らないんだから。
101デフォルトの名無しさん:2008/12/31(水) 15:10:32
> 1つ方法としてfriendがありますが、あとで拡張したくなったときにpublicメンバだけじゃ無理!
> というケースで元のクラスをいじらず拡張することができません。

それが可能になった場合、後で追加する場合には元のクラスをいじる必要はなくなるかもしれないが、
元のクラスの「実装」を変更したくなった場合に、追加したクラスに影響を与えることなく実現することが
できなくなる。
C++ としては >96 じゃないかな。

「当初の予定にないことを、あとで拡張したい」時に今のままでできないなら、一旦構成含めて
考え直す必要があるんじゃね?
102デフォルトの名無しさん:2008/12/31(水) 15:18:13
>「当初の予定にないことを、あとで拡張したい」時に今のままでできないなら、一旦構成含めて
>考え直す必要があるんじゃね?

これだからC++がダサいって言われるのですよね
やはりRubyが最高・最強です
103デフォルトの名無しさん:2008/12/31(水) 16:01:07
>>99-101
当初の予定にないことをあとで拡張しようとすることに無理があるようですね。

ありがとうございました。
104デフォルトの名無しさん:2008/12/31(水) 16:58:10
Rubyはブロックをendで閉じるのがどうしようもなくダサい。
105デフォルトの名無しさん:2008/12/31(水) 19:05:46
>>94
問題の一つとして、経験が足りないんじゃないのかな
何かプログラムを書いてたとして(得にライブラリ、フレームワークとか)、
将来、どこをカスタマイズするか、どこが不変的な部分かって
何度も同じプログラムを設計作り直しして、解ってくるもんだと思う。
106デフォルトの名無しさん:2008/12/31(水) 20:00:02
rubyはwindowsのこと考えてくれないから嫌だ。
107デフォルトの名無しさん:2009/01/02(金) 11:18:11
Boostなど外部ライブラリを使わず入力された文字列が
"2008/01/02 00:00:00"という形式になっているか確かめる方法ありませんか?
108デフォルトの名無しさん:2009/01/02(金) 11:26:06
APIや外部ライブラリを使わないなら、自分で書くしかないね
109デフォルトの名無しさん:2009/01/02(金) 11:27:10
std::tr1::regex使えばできるんじゃねぇの?
110デフォルトの名無しさん:2009/01/02(金) 11:37:10
それも外部ライブラリじゃないのか。
111デフォルトの名無しさん:2009/01/02(金) 12:49:42
別に外部じゃない
現標準でもないけど
112デフォルトの名無しさん:2009/01/02(金) 12:57:34
コンパイラがtr1に対応して無ければboostから引っ張ってくることになるのかな
ところでtr1って名前空間はずっとstd::tr1なの?stdに将来的には移ったりする?
113デフォルトの名無しさん:2009/01/02(金) 12:57:40
アドバイスありがとございます。
std::tr1:regexは何もインストールしなくても使えるんですね。試してみます。
114デフォルトの名無しさん:2009/01/02(金) 13:19:20
vectorって配列みたいな初期化方法ないんでしょうか?
vector<int> vec = {88, 99, 1100};
みたいな。
vector<int> vec;
vec.push_back(88);
vec.push_back(99);
vec.push_back(1100);
とするしかないですか?
115デフォルトの名無しさん:2009/01/02(金) 13:28:17
>>114
次期規格でそんな感じでできるようになるけど、現状では無理。
今のところは

static const int vec_def[] = { 88, 99, 1100 };
vector<int> vec(vec_def, vec_def + (sizeof vec_def / sizeof *vec_def));

みたいにするしかない。
116デフォルトの名無しさん:2009/01/02(金) 13:35:45
>>114
外部ライブラリを使うなら、boost::assignが使える。
http://d.hatena.ne.jp/faith_and_brave/20080312/1205312742
117デフォルトの名無しさん:2009/01/02(金) 13:37:06
>>112
http://en.wikipedia.org/wiki/C%2B%2B0x

>> Various full and partial implementations of TR1 are currently
available using the namespace std::tr1. For C++0x they will be
moved to namespace std. However, as TR1 features are brought
into the C++0x standard library, they are upgraded where
appropriate with C++0x language features that were not available
in the initial TR1 version.

C++0x で std::tr1 は std に移行するが、初めのTR1と同じではないようだ。
アップグレードされると。
118デフォルトの名無しさん:2009/01/02(金) 13:42:02
tr1 は所詮ドラフトだかんね。
119デフォルトの名無しさん:2009/01/02(金) 13:45:36
名前空間を分けてるのはそういうことなのか。それを理解して使えばいいってことなのね
120デフォルトの名無しさん:2009/01/02(金) 14:58:26
>>115 >>116
ありがとう
>>115の書き方初めて見た・・・しかも動いた。
第二引数は配列の先頭アドレスに要素数を足す???
121デフォルトの名無しさん:2009/01/02(金) 15:25:31
イテレータを指定して初期化してるだけ。
ポインタはランダムアクセスイテレータ。
122デフォルトの名無しさん:2009/01/02(金) 17:38:30
> 第二引数は配列の先頭アドレスに要素数を足す???
それであってる。
sizeof <配列名>を関数の仮引数以外で使った場合は配列全体の大きさを返す。

ついでに俺の疑問だがsizeof(vec_def) / sizeof(vec_def[0])って書き方のほうが一般的じゃないの?
123デフォルトの名無しさん:2009/01/02(金) 17:39:37
なんで[0]なの?
for(;;)に対する、while(1)的な気持ち悪さがある。
124デフォルトの名無しさん:2009/01/02(金) 17:44:01
>>123
これで正しいと思うよ。
配列に対して*vec_defの方がよっぽど気持ち悪い。
125デフォルトの名無しさん:2009/01/02(金) 17:46:29
[0] はマジックナンバーの出現に気持ち悪さを禁じ得ない。
126デフォルトの名無しさん:2009/01/02(金) 17:47:54
どちらも結局気持ち悪いことに変わりはない。
どちらも気持ち悪いのなら、マジックナンバーの無い方が良い。
127デフォルトの名無しさん:2009/01/02(金) 17:48:14
>>124
いや、正しいのはわかってるが、なんで1や2じゃなくて0なの?
128デフォルトの名無しさん:2009/01/02(金) 17:50:30
0なら確実にあるだろ
129デフォルトの名無しさん:2009/01/02(金) 17:50:43
sizeof に括弧をつけるのは素人っぽく感じる。
型にはつける必要はあるが。
130デフォルトの名無しさん:2009/01/02(金) 17:59:15
0は先頭だと十分理解できるだろ
数字なら何でもマジックナンバーとかいってんじゃねぇ
131デフォルトの名無しさん:2009/01/02(金) 18:04:07
サイズ 0 の配列を作れない以上、
1 でも問題ないね(デリミタ用途として仕様で許可されている)。
というか、そもそも sizeof は値を評価しないので、
存在しない要素を指定しても特に問題はない。
先頭だと理解できると言うが、先頭である必然性は特にない。

そもそも C++ ではこのタイプの要素数取得法を使うのは時代遅れで、
テンプレートを利用したタイプの安全な要素数取得法を使った方が良い。
132デフォルトの名無しさん:2009/01/02(金) 18:04:49
>>128
その理屈はおかしい。
sizeofの渡すときは実際にデリファレンスされないからなんでもいい。
133デフォルトの名無しさん:2009/01/02(金) 18:09:12
それよか、0よりも-1のほうが先頭じゃね?
134122:2009/01/02(金) 18:39:51
いろいろ勉強になった。みなさんありがとうございました。
135デフォルトの名無しさん:2009/01/02(金) 18:41:37
>>133
-2のほうがもっと先頭なんじゃね?
136デフォルトの名無しさん:2009/01/02(金) 18:43:29
static_cast<int>(1 << (sizeof(int) * 8 - 1))が先頭なんじゃね?
137デフォルトの名無しさん:2009/01/02(金) 19:09:13
つまんね
138デフォルトの名無しさん:2009/01/02(金) 19:39:02
配列の添え字はsize_tなのだが
139デフォルトの名無しさん:2009/01/02(金) 20:02:28
>>138
馬鹿をさらさなくていいよ
140デフォルトの名無しさん:2009/01/02(金) 20:23:43
ptrdiff_t
じゃね
141デフォルトの名無しさん:2009/01/02(金) 20:25:49
boost::beginとend使えばいいんですよ。
142デフォルトの名無しさん:2009/01/03(土) 11:50:39
>140
ptrdiff_t はポインタ間の減算結果の型じゃないの?
配列の添字については明確な記述が見つけられなかった。
143デフォルトの名無しさん:2009/01/03(土) 12:17:48
ローカル関数でオブジェクト作るときは普通newで作って関数の終わりでdeleteしますか?それともMyClass obj;みたいに作ります?
144デフォルトの名無しさん:2009/01/03(土) 12:20:28
>>142
x[n] は *(x + n) のシンタックスシュガーで、
ポインタ演算用の型は ptrdiff_t だから、
n は ptrdiff_t だな。
145デフォルトの名無しさん:2009/01/03(土) 12:29:00
>>143
CreateXXXみたいにオブジェクトの作成を目的とした関数ならnewしてポインタで返す。
単に処理の結果を返すだけなら、オブジェクトをそのまま返す。
146145:2009/01/03(土) 12:31:03
ごめん勘違いしてた。
そのケースでnew/deleteを使うのはサイズが大きすぎてスタックじゃ無理なときとか?
基本的にはnew使う必要ないと思う。
147デフォルトの名無しさん:2009/01/03(土) 12:59:25
C++はRAIIができるからfinallyがないという話なんですが、どうも納得できません。
後処理が必要なのはリソースの解放だけではないと思います。
たとえば、特定の処理を行うときだけ乱数種を固定したいという場合、

unsigned seed = Random::GetSeed();
try {
  Random::SetSeed(0);
  DoSomething();
} finally {
  Random::SetSeed(seed);
}

上のように書くのが自然だと思いますが、C++的には「RandomSeedMemorizer」のような
クラスを定義しなければならないということなのでしょうか?
148デフォルトの名無しさん:2009/01/03(土) 13:02:20
そう。
149デフォルトの名無しさん:2009/01/03(土) 13:03:02
クラス作っておけば使い回し利くだろ。
finally みたいなその場しのぎよりよっぽど良い。
150デフォルトの名無しさん:2009/01/03(土) 13:03:35
RandomSeedMemorizerではダメな理由がわからない。

DoSomethingがrandom generatorを引数で受けるようにするというのもあると思うけど。
151デフォルトの名無しさん:2009/01/03(土) 13:05:50
>>147
seedを固定できる乱数クラスを作る。
finallyのようなその場しのぎだと、記述忘れを起こしたりでバグの巣窟になる。。
152デフォルトの名無しさん:2009/01/03(土) 13:08:35
確かに乱数なら乱数クラス作るのが一番だな。
まあ、ファイル操作なら >>147 みたいなのが必要になるね。
153デフォルトの名無しさん:2009/01/03(土) 13:11:34
え?要らないでしょ・・・
154デフォルトの名無しさん:2009/01/03(土) 13:13:26
逐次的にファイルを読んでる時に
一時的にファイルの途中を読みたいときに使うでしょ。
155デフォルトの名無しさん:2009/01/03(土) 13:15:19
>>154
seek位置を保存再生するクラスを作れば?
156デフォルトの名無しさん:2009/01/03(土) 13:15:54
それFilePointerMemorizerでいいのでは
157デフォルトの名無しさん:2009/01/03(土) 13:17:54
>>148-150
やっぱりそうなんですね。
ただ、このような単純な処理までもクラスに分割してしまうことで、却って処理の流れが
不透明になるような気もするんですが、そういう議論はないのでしょうか。

>>151
それはRandomSeedMemorizerとは違うんですよね?
固定解除のタイミングが良くわからないんですが、たとえばどういうコードになりますか?
158デフォルトの名無しさん:2009/01/03(土) 13:21:08
>>155
それがまさに RandomSeedMemorizer と同じような処理だろ・・・。
159デフォルトの名無しさん:2009/01/03(土) 13:22:40
慣れの問題な気がするナー
finallyはクラスつくんなくていいけど
対応を目でイチイチ追わないといかんのがちょっと・・・
160デフォルトの名無しさん:2009/01/03(土) 13:22:42
>>157
そもそも流れにはあまり固執する必要は無い。
161147:2009/01/03(土) 13:41:13
>>159-160
なるほど。クラスの粒度に関する考え方の問題に似ているように思います。
ある意味、C++は小クラス主義を強制する言語なのかもしれないですね……。
162デフォルトの名無しさん:2009/01/03(土) 16:53:14
どちらかと言うと、C++はなにも強制しない言語なんだが。
163147:2009/01/03(土) 17:54:38
>>162
でも、委員会にはfinallyを標準化する意志はないみたいですよね。
無名関数であるlambdaを入れられるくらいなら、無名デストラクタであるfinallyを
入れられない理由はないと思うんですが、思想的なものが影響してるのかと思ったり。

JavaにもC#にもDにもfinallyがあるのに、C++にだけはないなんて。
164デフォルトの名無しさん:2009/01/03(土) 17:56:54
他にあるから入れる、というのはあんまりな・・・
165デフォルトの名無しさん:2009/01/03(土) 18:08:50
つか、ここでボヤいててもしょうがないと思うが。
166デフォルトの名無しさん:2009/01/03(土) 18:15:54
いやこのスレには割とC++0x標準化委員会のメンバーがいたりする
167デフォルトの名無しさん:2009/01/03(土) 18:16:53
finally がどうしても必要なのはガベコレがあるからであって、
ガベコレのない C++ はデストラクタに頼ったので良い、という考え方なのだろう。
168デフォルトの名無しさん:2009/01/03(土) 18:21:37
lambdaがあればDのscope(exit)みたいなものを実装できないか
finallyはしらね

struct scope_exit_impl {
scope_exit_impl(std::reference_closure<void ()> const& f):f(f){}
~scope_exit_impl(){f();}
std::reference_closure<void ()> f;
};
#define scope_exit(hoge) scope_exit_impl guard([&](){ hoge })
scope_exit( 後始末() );
169デフォルトの名無しさん:2009/01/03(土) 18:23:16
finally使うと処理がユーザコード側に分散するからなあ
170デフォルトの名無しさん:2009/01/03(土) 18:43:17
やろうと思えばローカルクラス使ってこんなのはできる
めんどくさいけどな

void func()
{
  class finally{
    ~finally(){
       //...後始末
    }
  } finally_;

  try{
    //...なんかする
  }catch(...){
    //...万が一に備えて
  }
}
171デフォルトの名無しさん:2009/01/03(土) 18:51:01
こんな感じとかか。
まずやらんが。

void func() {
 {
  struct local_t {
   local_t() : a(1) {
   }
   ~local_t() { // finally
    std::cout << a << std::endl;
   }
   int a;
  } local;

  try {
   throw std::exception();
   local.a = 2;
  } catch (...) {
  }
  // ここには何も書かない
 }
 std::cout << "end" << std::endl;
}
172147:2009/01/03(土) 19:16:47
>>167
DにはGCがありますが、C++のようなRAIIとfinallyの両方をサポートしています。
理想論はともかく、現実的にはやはり両方あった方が便利ということかと。

>>170-171
そういう方法があるのは一応知ってますが、推奨される書き方ではないですよね。
ここで質問したのは、C++にfinallyがなくても大丈夫な理由を説明してくれる人が
いるかと思ったからなのですが、やたら小さいクラスは作りたくないしトリッキーな
方法も使いたくない、だけど例外のメカニズムは使いたいという要求に応える回答は
今のところないようです。
173デフォルトの名無しさん:2009/01/03(土) 19:20:15
まーな。ここの連中レベル低いし。
174デフォルトの名無しさん:2009/01/03(土) 19:20:20
いや、GC ないから RAII が必ず動く事が保証されるので
RAII で大丈夫、ちうのが回答なわけだが。
175デフォルトの名無しさん:2009/01/03(土) 19:21:19
>>174
GCあっても、RAIIが動かなくなるなんてことはない。
この二つは直行概念だよ。
176デフォルトの名無しさん:2009/01/03(土) 19:25:05
まあ、C# の using や D の scope みたいなのを使えば動くからね。
でも、こいつらって finally が導入された後に導入されたんじゃね?
177デフォルトの名無しさん:2009/01/03(土) 19:29:44
GC管理オブジェクトをRAIIすることはできないんだってば
ファイナライザは不確かすぎてリソースの確実な開放のような重要な仕事を任せることは出来ない
だからfinallyが必要になる

逆にRAIIしたいオブジェクトはGCの管理から外れてないといけない
というか後始末はプログラマの仕事になるから任せるわけにはいかない
その区別のためにDではscopeなんていう予約語があるし
C++/CLIではポインタとハンドルを分けてる
178デフォルトの名無しさん:2009/01/03(土) 19:30:31
>>176
Dのscopeはクラス(参照型)でRAIIを実現するためのキーワード。
(もちろん、finallyのシンタックスシュガーとも言える)

Dでも構造体(値型)をスタックに確保すれば、C++のクラス(値型)と同様のRAIIを使える。
179デフォルトの名無しさん:2009/01/03(土) 19:35:42
>>176
C#は1.0の最初からusingを持っている。
一般的にはusingが推奨されているし、実際コーディングしていてもfinallyなんて滅多に使わない。
180デフォルトの名無しさん:2009/01/03(土) 19:36:57
>>179
そうなのか。
ま、やっぱり finally は GC 使っちゃった場合の
苦肉の策でしかないわな。
181デフォルトの名無しさん:2009/01/03(土) 19:39:38
>>172
「やたら小さいクラスは作りたくない」
この主観が邪魔してるだけだろ。

小さいクラスを作ってもたいしたデメリットは無いだろうし、あったとしても
同じ後始末処理を使いまわせるメリットに勝ることはないだろう。

auto_ptr は小さいクラスだが、コレ使わずに finally 使えとか言われたら死ねる。
182デフォルトの名無しさん:2009/01/03(土) 19:42:17
RAII クラスは関数と同じくらいの気軽さで作って良い。
183デフォルトの名無しさん:2009/01/03(土) 19:46:19
>>177
それがfinallyである必要はない。
DのscopeやC#のusing、C++/CLIの(参照クラスの)デストラクタのように、
GC付き言語でfinallyよりC++のデストラクタに近いものはいくらでもある。
184デフォルトの名無しさん:2009/01/03(土) 19:52:33
>>183
DやC#やC++/CLIはGC付き言語だけど
そこで挙げてるようなのはGCの管理外だぞ
だからC++のデストラクタに近いものなのは当たり前だし、GCとは別に用意されてるんだ

わかってる?大丈夫?
185デフォルトの名無しさん:2009/01/03(土) 19:52:53
もっと議論読んでくれよ・・・
186デフォルトの名無しさん:2009/01/03(土) 20:24:07
>>184
C#やDなどの場合、finallyとusing/scopeはお互い等価に変換できるシンタックスシュガーの関係。
using/scopeも後始末用のメソッドを呼ぶだけで、インスタンス自体のメモリの解放はGC任せ。

「だからfinallyが必要になる」って書いているけど、
本当に必要なのはfinallyそのものではなく「確実に後処理を行える機構」。
finallyはそのための手段の1つでしかない。もちろんusingやscopeもその手段に該当する。
187デフォルトの名無しさん:2009/01/03(土) 20:33:32
まあ、特に finally とか必要ないと思う。
finally でハードコーディングするよりゃRAII 使え。
188デフォルトの名無しさん:2009/01/03(土) 20:43:15
http://ja.wikipedia.org/wiki/%E5%AE%9F%E5%BC%95%E6%95%B0%E4%BE%9D%E5%AD%98%E3%81%AE%E5%90%8D%E5%89%8D%E6%8E%A2%E7%B4%A2
この仕組みは現在使われてる全てのコンパイラが対応していると見ていいんでしょうか?
あと、実引数が2つ以上の時の挙動も決まってるんでしょうか?
189デフォルトの名無しさん:2009/01/03(土) 20:57:07
もちろん、今時のコンパイラなら実装されている。
でないとstd::operator <<とかstd::operator +とかstd::basic_stringなどが死ねる。
引数が複数ある場合も規格には載っている。

ただ、規格通りに実装されているかというと、怪しいコンパイラがちらほらあったと思う。
190デフォルトの名無しさん:2009/01/03(土) 20:57:24
俺が使っているオレオレコンパイラは対応してないな
191デフォルトの名無しさん:2009/01/03(土) 21:31:29
レスありがとうございます。
引数が複数ある時の挙動には注意が必要なんですね。
192デフォルトの名無しさん:2009/01/03(土) 21:57:40
引数が複数ある場合よりも、テンプレートで予期せぬ名前空間まで探索されることに気を付けろ。
193デフォルトの名無しさん:2009/01/03(土) 22:39:30
>>192
template <class T>
void Hoge(T t){
  F(t);
}
こういう事ですか?
194147:2009/01/03(土) 23:00:39
>>181
auto_ptrのように標準で用意されているクラスを使えばそれでよしというのなら
まだ納得できるのですが、自分で小さいクラスを書かなければいけないとなると、
やはり小クラス主義の思想を強制されているように感じてしまいます。

RAII方式のデメリットといえば、
(1) 一つの関数内だけでシンプルに記述できない
(2) finallyで書いた場合よりも行数が増える
(3) クラスの名前を考えなければならない
(4) 後処理の実装を再確認するときにも一手間増える
(5) クラスを定義するために別の場所に移動するとき一瞬思考が途切れる
などでしょうか。

これらを差し引いてもメリットが上回ると心の底から納得することができれば、
面倒な思いをしなくても済むのでしょうけれど……。
195デフォルトの名無しさん:2009/01/03(土) 23:01:44
(2) finallyで書いた場合よりも行数が増える

使い回せばむしろ減る。
196147:2009/01/03(土) 23:04:08
>>195
使い回せばと言いますけど、1回しか出現しないような処理も結構あるわけですよ。
197デフォルトの名無しさん:2009/01/03(土) 23:18:33
スコープはずれた時にコンストラクタ引数で渡した関数を呼び出すようなクラスを用意しとけば使い回せるじゃん。
C++0x で lambda が書けるようになれば↑と組み合わせてほとんど解決されるんじゃね?
lambda って言っても実質ローカルクラスなんだけどさ。
198デフォルトの名無しさん:2009/01/03(土) 23:19:00
OOPの理想の最終形態は自分でクラスを作らない、具体的な実装を知る必要もない
というところにいくので1-5はデメリットにならない。
199デフォルトの名無しさん:2009/01/03(土) 23:23:40
小クラス主義って何だ?大クラス主義もあるのか?

クラスというのは機能の単位だ
長い関数が悪であるのと同じように、何でもかんでも詰め込んだ巨大クラスも悪だし、
そういうクラスは適切に分割するのがOOPの基本
それを小クラス主義と呼ぶのなら的外れだし、大クラス主義とやらはただのヘタな設計だ
200デフォルトの名無しさん:2009/01/03(土) 23:26:34
ローカルクラスにはしないけど、
ファイルローカルなクラスにすることはあるね。
201デフォルトの名無しさん:2009/01/03(土) 23:28:32
>>194-197
>170-171 の方法を知ってれば (1),(4),(5) みたいなのがデメリットは無いだろ。
ついでに (3) もわりとどうでも良くなる。

(2) については 195 の言うとおりで、「1回しか出現しない」のが「結構ある」なんてのは、
似たような処理を関数にまとめられないのと同じで下手なだけでしょ。
202デフォルトの名無しさん:2009/01/03(土) 23:37:07
今気が付いたんだけどスレのテンプレがpart63を最後になくなってる。
次スレでは復活させたいな。
203デフォルトの名無しさん:2009/01/03(土) 23:40:06
リソースの構築と後始末の処理という大がかりで複雑で重要な仕事に
クラスを1つ割り当てることを「小クラス主義」というのは正直理解しがたい
147にとってクラスとは何なんだ
204147:2009/01/03(土) 23:59:57
>>197 >>201
今でもマクロなどを使って強引に書けなくもないですし、finallyに非公式対応している
C++コンパイラもあるので、標準など気にせず使ってしまうという選択もありますね。

>>203
個人的な考えでは、RAIIがあるからfinallyは要らないという理屈は、もともとメモリや
ファイル等のわかりやすい例しか考えていなかったのではないかと想像しています。

ですが現実には、リソースに一対一で対応していない、もっと抽象的なものを保存して
おきたい場合もあるわけですよね。乱数種やファイルポインタもそうですし、標準出力の
フォーマットとか、クラス内部の一時的なモード設定等。
そういったものもすべてデストラクタで処理するべしというのが最近の風潮のようですが、
C++の設計者が最初からそういう意図だったのかは結構疑問な部分があります。
205デフォルトの名無しさん:2009/01/04(日) 00:02:41
思ったんだけど、>147の例がおかしくね?
普通はseedも含めてrandomクラスにするんじゃないの? boost::randomみたいに。
seedだけ入れ替えたりするからこんな格好悪い操作が必要になると思うんだけど。

グローバル的なものを使うのならfinallyみたいなグローバルな仕組みがあると便利そうだけど、
それはかなりC的な使い方だよね。

206デフォルトの名無しさん:2009/01/04(日) 00:09:09
>204
C++にとって、リソースの所有権をハッキリさせることは非常に重要だよ。
普通はインスタンスが所有するから、RAIIで管理するのは自然なことだよ。
複数のインスタンスで管理するならshared_ptrだし、プログラム全体で管理するならSingleton/Multitonじゃない?

207147:2009/01/04(日) 00:20:25
>>205
そうですね。C的な設計のライブラリを使う場合などに特に問題になります。
うまく設計することで、後始末処理が必要になるケース自体を減らすことは可能では
あると思います。

>>206
リソース自体をRAIIで管理することには全く反対していないですよ。
208デフォルトの名無しさん:2009/01/04(日) 00:25:15
>>147 の人気に嫉妬
209デフォルトの名無しさん:2009/01/04(日) 00:27:24
>>204
わからんなぁ……
問題はリソースに対応してるかどうかは関係なく、後処理が必要かどうかだろ?
そしてデストラクタは間違いなくリソース後処理のための機能に違いない
何か不満があるのか

「RAIIがあるからfinallyは要らない」というのも順番が違うよなぁ
JavaにC++的なデストラクタがないがためにRAIIが出来ないから
代わりに導入されたのがfinallyという機能じゃないの?
210デフォルトの名無しさん:2009/01/04(日) 00:30:32
リソース以外に挙げてる例が全部使いまわしの効くものなんで、 >196 が口からでまかせにしか見えない。
211デフォルトの名無しさん:2009/01/04(日) 00:33:18
C++にfinallyを採用しない理由を禿に聞いたら多分こんな答えが返ってくると思う

・新しい機能を提供しない
必要になれば>>170-171の方法で同じ機能のものをいつでも作ることが出来る

・必要とされる機会が少ない
RAIIを適切に行っていれば、finallyが必要になることはほとんど(あるいは全く)ない

・よくないコーディングスタイルを推奨する
「使った後はfinallyで○○を始末してね」のようなクラス設計が行われるようになるおそれがある
言うまでもなく危険だし、RAIIの利点が全く殺されてしまう

RAIIのデストラクタでは出来ない何か大きな利点がないと、禿を説得するのは難しかろう
次々規格でGC導入考えるらしいから遙か未来にはどうなってるかわからんけどね
212デフォルトの名無しさん:2009/01/04(日) 00:34:28
>207
リソース解放以外にfinallyが必要になるケースはあまり無いような気がするけど……
「一時的な設定変更」も、そもそもそういうことが必要になること自体が良くない設計じゃない?
213デフォルトの名無しさん:2009/01/04(日) 00:45:57
つーか、なんでJavaにはデストラクタないんだ
コンストラクタだけって、そっちのほうがよくわからん
214デフォルトの名無しさん:2009/01/04(日) 00:48:16
GC に任せっきりだからさ
215デフォルトの名無しさん:2009/01/04(日) 00:50:27
>>213
ファイナライザならあるよ
216デフォルトの名無しさん:2009/01/04(日) 00:57:47
これを思い出させる流れだ。
ttp://oshiete.nikkeibp.co.jp/kotaeru.php3?qid=2012323
217デフォルトの名無しさん:2009/01/04(日) 00:59:44
破棄処理のタイミングとメモリ解放のタイミングは別々でいいのに、
ごっちゃにしちゃったのがまずいんだろうね。

C++ のデストラクタと Java とかの GC との組み合わせが実現すると良いんだろうなぁ。
218147:2009/01/04(日) 01:00:25
この疑問を持ったのは、とあるフリーソフトのソースを読んで、一時的な状態を保存して
デストラクタで復帰させるだけのクラスが大量にあるのに気づいたからなのです。
で、それらのクラスの多くは1回か2回くらいしか使われていなかったりするわけです。
もしC++の標準機能にfinallyがあれば、このコードはずいぶんシンプルに書き直すことが
できるだろうなあと感じました。(ソフトの具体名は差し控えさせてください)

多分「設計が悪い」という意見が一番的を射ているのだろうと思います。かといって
変なトリックを使わない前提でどう直したら良いのかはわかりませんけれど……。

皆さんたくさんのレスありがとう。これにて引っ込みます。
219デフォルトの名無しさん:2009/01/04(日) 01:04:12
>>170-171の方法で、と言うが、f1のように使えない限り
とても代わりに使えるレベルとは言い難いが。
また、仮にf1が通っても、可読性は損なわれているように見える。

struct file_t{
void open();
void close();
};

void f0()
{
file_t file;
try{ file.open(); }
catch(...){}
finally{ file.close(); }
}

void f1()
{
file_t file;
struct finally_t{
~finally_t(){ file.close(); } // error C2326
} finally_;
try{ file.open(); }
catch(...){}
}
220デフォルトの名無しさん:2009/01/04(日) 01:08:05
>>212
Direct3DとかBegin()とEnd()がチラホラあるライブラリでも必要
221デフォルトの名無しさん:2009/01/04(日) 01:09:02
>218
そういうのだったら関数オブジェクト使った方がスマートだよな。
まあ、一時的に値を変更してまた復帰させなきゃいけないというのはけっこう危険だから、
新しくインスタンス拵えてそっちを使う方が良いと思うけど。
222デフォルトの名無しさん:2009/01/04(日) 01:20:14
こんなfinalというクラスを作れば
#include<functional>
class final{
    std::function<void()>value;
public:
    template<typename T>
    final(T value):value(value){}
    ~final(){value();}
private:
    final(const final&);final&operator=(const final&);
};

これだけで出来たぜ!(C++0xです)

file_t file;
file.open();
final f=[&]{file.close();};

まぁfileのcloseなんて100人いたら100人ともRAIIでやるがな
223デフォルトの名無しさん:2009/01/04(日) 01:22:53
>>219
そんなときはf1を丸ごとクラスにするという手がある

struct f1{
 file_t file;

 f1(){
  struct finally_t{
   ~finally_t(){ file.close(); }
  } finally_;
  try{ file.open(); }
  catch(...){}
 }
};
224デフォルトの名無しさん:2009/01/04(日) 01:27:11
ごめんおかしかった
225デフォルトの名無しさん:2009/01/04(日) 01:28:05
>>222
function のコンストラクタで bad_alloc が投げられると漏れるな。
226デフォルトの名無しさん:2009/01/04(日) 01:36:17
一応言っておくけどファイルクローズは失敗する可能性があるからRAII厳禁だぞ
227デフォルトの名無しさん:2009/01/04(日) 01:41:08
>>225
ああ、たしかに考えてなかった。
正しくはこうか。

template<typename T>
final(T value)try :value(value)
{}
catch(...){value();throw;}

228デフォルトの名無しさん:2009/01/04(日) 01:41:34
>>226
無視していいという状況ではRAIIで任せても問題ない。

使い方として、無視してよい場合と駄目な場合の両方が考えられるなら、
fstreamみたいにcloseとデストラクタの両方を用意すればよい。
229デフォルトの名無しさん:2009/01/04(日) 01:44:08
ああ、コンストラクタでの例外は、
throwを書かなくても再送されるからthrowを書く必要は無かった。

>>226
ぶっちゃけファイルクローズが失敗するような
末期的な状態になったらどうしようもなくね?
230デフォルトの名無しさん:2009/01/04(日) 01:45:19
>>226
fstream だと、デストラクタで fclose() させたときの失敗は報告されないことになっている
ものの、いちおう RAII には従ってる。

RAII 禁止じゃなくて、使う側で RAII まかせにしちゃいけない、の間違いじゃない?
231デフォルトの名無しさん:2009/01/04(日) 01:46:17
ぶっちゃけ close で失敗した所で何をすればいいのん?
232デフォルトの名無しさん:2009/01/04(日) 01:46:59
末期的でなくても失敗するよ
ネットワークドライブ上のファイル扱ってる間に回線切れたとかな

ファイルクローズ失敗を無視して良い状況というのはほとんどない
RAIIはファイルに使ってはいけない
233デフォルトの名無しさん:2009/01/04(日) 01:51:14
>>227
T のコピーで例外がスローされるかもしれないから、まだもうちょっと危険な感じ。
ここで引数を reference_closure に限定するといいらしい。
234デフォルトの名無しさん:2009/01/04(日) 01:51:32
>>231
エラーログに書き込んでから、復旧不能なエラーだったら諦めて無視するかプログラムを落とす
そうでなかったら成功するまでcloseを試みる
どうしてもダメならタイムアウトしてOSに通知する
closeの仕事が本筋の処理が中断するとまずいようならcloseを繰り返すためのスレッドを作る
こんなところか
235デフォルトの名無しさん:2009/01/04(日) 01:56:36
>>233
むー例外安全とは難しいなぁ。
個人的には、const T&とT&,T&&辺りを気合でゴリゴリ書いて、
関数オブジェクトにも対応させたいなぁ。
でもreference_closureに限定させたほうが楽そうだな。

>>232
了解です。確かにRAIIじゃ不完全ですね
236デフォルトの名無しさん:2009/01/04(日) 01:57:03
>>234
なるほど・・・。
まあ、そのあたりをデストラクタで(例外を一切発生させずに)行えばいいという気もしなくもない。
スレッド使う場合は、ワーカスレッドを事前に用意しておく必要があるけども。
237デフォルトの名無しさん:2009/01/04(日) 01:59:27
>>231
デストラクタの外で close() して、普通に例外投げりゃいいんだよ。
238デフォルトの名無しさん:2009/01/04(日) 02:03:08
ファイルを管理する singleton の大ボスを作っておけばいいんだよ。
デストラクタで close に失敗したら、そいつに管理を委譲する、と。
239デフォルトの名無しさん:2009/01/04(日) 02:22:03
>>231
それが出力ファイルの close なら失敗した旨をユーザーに通知する必要があるだろ。
240デフォルトの名無しさん:2009/01/04(日) 03:23:14
std::fstreamでもやっているとおり、
- 処理の最後にcloseを呼ばせるようにドキュメントしておく
- デストラクタの実装では、closeされてなかったらcloseして、
  もし例外が発生したら呑み込んでしまうことにする
とするのが現実的な落としどころだと思われ。

正常系でcloseせずにデストラクタに行って例外が呑み込まれてしまったら
それはユーザ側のコードが悪い。

異常系ではcloseが呼ばれずにデストラクタが直接呼ばれることもあるかもしれないが、
その場合closeが失敗するとアクティブな例外が同時に2つ存在することになるので
いずれにせよどうにもならない。
241デフォルトの名無しさん:2009/01/04(日) 03:42:56
想像してみたけどcloseが例外を投げることを考えた場合、
処理が冗談抜きで面倒だなぁ。

try,catch,finallyモデルを採用しても書くのがマジで面倒そう

try{
  file.open();
  file.close(); 例外飛ぶから無理
}finally{
  try{
    file.close();
  }catch{
    //どうする?
    //例外の再送は2重に例外投げるかもしれないから出来ない!
  }
}

これでも面倒だけどC++にはfinallyないからRAIIで書くはめになってさらに面倒

俺はこんな面倒なことになるなら、closeは例外投げない!
という前提でクラスを設計したくなってくる。
例外を投げれる柔軟性なんかいらんわー。
242デフォルトの名無しさん:2009/01/04(日) 03:46:13
>>241
closeは例外投げるがデストラクタは投げないとすれば、基本的には問題ない
243デフォルトの名無しさん:2009/01/04(日) 09:44:42
でもどっかにエラーださないと
win32のデバイスコンテキストまわりぐれーに開放されてるのかされてないのかわからない状態になるな
でも個人的にはスルー(笑)
244デフォルトの名無しさん:2009/01/04(日) 09:55:35
デストラクタで例外投げたらどんな動きになるん?
245デフォルトの名無しさん:2009/01/04(日) 10:31:35
別にそれ自体はなんともならん、普通のメンバ関数で投げたときと一緒
でもそのクラスの配列作って delete [] したときとかに複数要素が例外投げてくれると、アウトだろ?
246デフォルトの名無しさん:2009/01/04(日) 10:32:25
ごめん流れ読めてないね
ほんとごめん
247デフォルトの名無しさん:2009/01/04(日) 11:36:36
配列 delete じゃなくてもアウトだよ。
デストラクタはメモリの開放前に呼ばれるわけだから、
デストラクタで例外投げられたらメモリリークする。
248デフォルトの名無しさん:2009/01/04(日) 11:54:44
それは違うだろー、自身のこといってるならそれは解放されるし、メンバのことだったらそれは単に書き方の問題だろう

まぁアウトなのが配列のときだけではないのはそりゃそうだが
249デフォルトの名無しさん:2009/01/04(日) 12:04:57
俺はデストラクタで例外が発生する場合は
自前で処理できる分を処理して再送してるな。
250デフォルトの名無しさん:2009/01/04(日) 12:09:47
デストラクタで例外を投げたら、基本クラスのデストラクタはどうなるのとか、例外の巻き戻し中だったらどうなるのとか悩む
251デフォルトの名無しさん:2009/01/04(日) 12:12:19
例外がスローされ、ローカル変数がデストラクトされる過程でまた例外が起きたら
terminateが呼ばれてあぼーんだべ
252デフォルトの名無しさん:2009/01/04(日) 12:17:00
デストラクタで例外投げないようにすればRAIIでもOKだよ、って
その持っていき方がそもそもおかしい。

>closeは例外投げるがデストラクタは投げないとすれば、基本的には問題ない
それが出来るんなら、closeでも例外なんて投げないよ

>>228,230
だから結局、ファイルクローズはRAIIでやんの禁止なんだろ。
253デフォルトの名無しさん:2009/01/04(日) 12:29:27
例外巻き戻し中のfinallyで例外投げたらどうなるの
254デフォルトの名無しさん:2009/01/04(日) 12:29:52
>>253
例外が投げられるだけ
255デフォルトの名無しさん:2009/01/04(日) 12:30:48
ああ、catch でさらに throw された状態で
さらに finally で throw された時のことか。
誤解してた。
どうなんだろ。俺は知らん。
256デフォルトの名無しさん:2009/01/04(日) 12:31:29
>>252
>>236>>238 じゃだめなの?
257デフォルトの名無しさん:2009/01/04(日) 12:40:49
>>255
Javaの話なら、catchで投げた例外は消滅する
258デフォルトの名無しさん:2009/01/04(日) 13:02:50
>257
それじゃ例外安全にはならないね。RAIIとあんまり変わらないな。
こういうのはGC組んだ方が良さそうだね。
close()が成功する or 失敗したときの後処理が終了するまでdeleteされないようにするとか。
後でアクセスできるように>238みたいな仕組みも必要か……

259デフォルトの名無しさん:2009/01/04(日) 13:13:00
C++ だとスタック巻き戻し中に
デストラクタで例外投げられたら
std::terminate が呼ばれてシボンヌ
260デフォルトの名無しさん:2009/01/04(日) 17:21:58
>>252
>>closeは例外投げるがデストラクタは投げないとすれば、基本的には問題ない
> それが出来るんなら、closeでも例外なんて投げないよ

なんで出来ないと思うの?
261デフォルトの名無しさん:2009/01/04(日) 17:50:45
こういう実装でいいと思うんだ。
int close_file(file_t); //失敗時は非0を返す。
class file {
public:
close() {
int error = close_file(f)
f = 0;
if (error)
throw file_exception(error);
}
~file() {
if (!f)
close_file(f);
}
private:
file_t f;
};
閉じるときの例外を無視してはならないという主張は全面的に同意だけど、
それ以外の操作で例外が投げられたときは、とりあえずファイルを閉じてリークを防ぐべきだと思う。
あと、読み取りだけの場合は、書き込んだときほどcloseに慎重になる必要はないのでは?
262デフォルトの名無しさん:2009/01/04(日) 22:32:00
たとえばpod64<int>::typeと書けば64bit int型になるようなテンプレートを書こうと思い、以下のようなテストプログラムを組みました。

#include <iostream>

template <typename _Pod,bool _Is64=(sizeof(_Pod)>=8) >
struct pod64{
  typedef _Pod type;
};

template <typename _Pod>
struct pod64<_Pod,false>{
  typedef long _Pod type; // ※
};

int main(void){
  pod64<unsigned int>::type l = 10;
  std::cout << l << std::endl;
  std::cout << sizeof(l) << std::endl;
  return 0;
}

ネーミングが正しくないのは承知で、charとかvoidとかshortとか入れると発狂されるのも承知の上で、
pod型を入れると64bitより小さければlongで修飾するように書いたつもりだったのですが、コンパイルが通りませぬ。
※の行でtypeが型として認識されないようです。
なんとなくそれは当たり前だなあとはわかるのですが、かわりにどのように記述すればいいのかよくわかりません。
どのように書くのが正しいのでしょうか。
263デフォルトの名無しさん:2009/01/04(日) 22:35:17
>>262 int64_t
264デフォルトの名無しさん:2009/01/04(日) 22:38:34
>>262
template<typename T> struct add_long;
template struct add_long<int> { typedef long int type; };
template struct add_long<long int> { typedef long long int type; };

って感じで、特殊化を全部並べとけばいいんじゃね?
265デフォルトの名無しさん:2009/01/04(日) 22:43:38
typedef typename long _Pod type;

テンプレート中で型名を使う時はtypenameが必要
266262:2009/01/04(日) 23:02:45
>>263
うえーん(´・ω・`)

>>264
やっぱりそうするしかないんでしょうか。。。

>>265
そういう問題ではないようです。
というのも、longをconstにしたらtypename無しで問題なくコンパイルされ、
というかむしろtypenameを付けるとコンパイルが通らなくなり、
longのままだとtypenameがあっても無くてもコンパイルが通らないので。
純粋にlongがconstのような修飾子とは判断されないということだと思います。

>>263の方法が一番現実的かつ正確な気がしてきました。
long long long long とかつないで行ったときに92bitとか128bitになる環境だったら名前が正しくないのも気持ち悪かったので、
>>263の方法でいってみます。ありがとうございました。
267デフォルトの名無しさん:2009/01/04(日) 23:18:28
>>266
typename は本来必要な箇所になくても通るコンパイラがあるから、
あんまり通った通らないはあてにしない方がいい
268デフォルトの名無しさん:2009/01/04(日) 23:46:59
long int でひとつの型なんだろ
longはconstのような修飾子じゃないんでしょ
そういうのやりたきゃプリプロセッサでやるこった
269デフォルトの名無しさん:2009/01/04(日) 23:58:51
long は型指定子(type-specifier)で
const は cv-修飾子(cv-qualifier)だな。
specifier と qualifier のニュアンスの違いはよく分からんが。
270デフォルトの名無しさん:2009/01/05(月) 00:03:36
とりあえず dependent name じゃないから typename は付けられない。

型に対する演算がしたいなら基本は >264。

boost::mpl 使えば多少は省力化できるかも。
template<typename Pod>
class pod64 {
    typedef boost::mpl::map<
        boost::mpl::pair<int,long int>,
        boost::mpl::pair<long int,long long int>,
        boost::mpl::pair<long long int,long long int> /* 必要なだけ追加 */
    > TypeMap;
public:
    typedef typename boost::mpl::at<TypeMap, Pod, void>::type type;
}
271デフォルトの名無しさん:2009/01/05(月) 22:26:01
すみません、ちょっと質問です。
テンプレートコンストラクタでテンプレート引数を指定してコンストラクトするにはどうしたらいいんでしょうか?

struct A {
 template<typename T>
 A() {};
 template<typename T>
 A(T t) {};
}

A a0(1); //OK
A a1; //error

わざわざ使わない実引数を指定しなきゃいけないのかな……
272デフォルトの名無しさん:2009/01/05(月) 22:47:03
struct A {
 //template<typename T>
 A() {};
 template<typename T>
 A(T t) {};
};
273デフォルトの名無しさん:2009/01/05(月) 22:58:25
>>271
template <typename T> struct Type { };

struct A {
 template <typename T> A(Type<T>) { ... }
};

A a(Type<int>());

最適化で Type オブジェクトの引き渡しは消えるはず。
274271:2009/01/06(火) 00:17:30
サンクスです。

>272
class A {
public:
 template<class T> A() : a_(a<T>()) {};
private:
 unsigned int& a_;
 template<class base_t> static unsigned int& a() { static unsigned int r(0); return r; };
};
というのをやりたいので、それだとNGですね。

>273
やっぱりType2Type使うのが妥当ですかね。
275デフォルトの名無しさん:2009/01/06(火) 00:34:55
>>274
そのTとbase_tは何に掛かってくるの?
やっぱ>>272が妥当じゃないか
276271:2009/01/06(火) 01:00:17
>275
つまりは型の種類ごとに挙動を変えたい(rの値を変更する)ということですね。

class B {};
class C {};

A ab0(B());
A ac0(C());
A ab1(B());

みたいにしたときに、ab0とab1の挙動を共通にしたいということです。
……まあ、MC++D参考にマルチディスパッチをこしらえているだけですけどね。
277デフォルトの名無しさん:2009/01/06(火) 01:15:14
派生クラスによって、
色々な型の返却値、引数のメンバ関数を持たせることの出来る
基本クラス、派生クラスを作成したいのですが、
よい手を教えてください。

具体的には派生クラスによって、メンバ関数funcが、
o intの引数を2つ取り、引数の足し算の結果を返却する
o doubleの引数を2つ取り、大きい方の値を返却する
o doubleの引数を1つ取り、cos(引数)の結果を返却する
というようなバリエーションがとれるような派生クラスに
したいのです。
お願いします

278デフォルトの名無しさん:2009/01/06(火) 02:09:18
それメンバ関数である必要ないじゃん
グローバル関数にして関数ポインタ使い回すか
関数オブジェクトにして使い回すかでいいんじゃね
279デフォルトの名無しさん:2009/01/06(火) 05:20:19
>>277
やりたいように書けばそれで問題ないように見えるんだけど、
ためしに書いてみたコードでも晒してみてくれまいか。
280デフォルトの名無しさん:2009/01/06(火) 08:14:18
struct T {
 enum { value = 1, }
 static T *create();
 typedef T *iterator;
};

void f() {
 T *p = p->create(); // OK
 int n = p->value; // OK - std::string::nposとか長いんだよ
 p->iterator it = p; // NG - autoだけ先行導入しろよ
}
281277:2009/01/06(火) 13:25:47
すいません。説明不足なのでつけたします。
やりたいことは、派生クラスを基本クラスにアップキャストして
vectorなどに保存しておいて、
vectorの先頭から、派生クラスとしてメンバ関数を実行する
というようなことをやりたいのです。

実行側からすると、どのような関数かはvector内を見るまで
わからないけど関数に合せて実行したいということになります。

>>278
メンバ関数にこだわる理由は特にないのですが、
任意の返却型、引数型を表わせる関数ポインタというのがあるなら、
それを使えそうな気がします。

>>279
今は時間がとれないので夜晒します
282デフォルトの名無しさん:2009/01/06(火) 13:28:26
>>281
boost::function の出番だな。
あとは、 vector を操作しながらそれぞれの関数を呼び出すところで
引数をどう渡すつもりなのかによる。
283277:2009/01/07(水) 00:22:33
#include <iostream>
#include <vector>

using namespace std;

int op_plus(int x, int y)
{
return x + y;
}

double op_cos(double x)
{
return x;
}

template <class TRet, class TArg>
class Op {
protected:
int arg_num;
vector<TArg> args;
TRet result;
public:
Op(int n) : arg_num(n) { }
virtual void exec();
void add_arg(TArg arg) { args.push_back(arg); }
};
284277:2009/01/07(水) 00:22:49

class Plus : public Op<int, int> {
public:
void exec() {
result = op_plus(args[0], args[1]);
}
};

class Cos : public Op<double, double> {
public:
void exec() {
result = op_cos(args[0]);
}
};

int main(int ac, char *av[])
{
vector<Op<int, int> > vec;

return 0;
}
285277:2009/01/07(水) 00:29:07
関数ポインタは難しかったので、
virtual void exec();の関数内で、
派生クラス毎に任意の関数を呼ぶようにして、
テンプレート使ってみたのですが、
main()内のvectorを作る時点で、Opの型を決める
必要があるようで、
>>281の意図していたものにはなりませんでした。

main()からは、1種類のクラスとしてvectorで扱いたいのですが、
アイデアがないというところです。
286277:2009/01/07(水) 01:39:52
>>282
引数の渡し方は、vector内の隣りで
実行完了したクラスの返却値をもらうとか、
クラスのメンバに登録してから、実行するのでもいいです。

boostについても調べてみたのですが、std::mem_funすら
わかっていないのでかなり敷居が高そうです。
性能も必要なので最悪、色々な種類の関数ポインタを
unionした構造体にしてしまうのがいさぎよい気もしてきました。
287デフォルトの名無しさん:2009/01/07(水) 02:26:52
結局何がやりたいかよくわかんないんだけど
funcのシグニチャは派生クラスごとにてんでバラバラなんだろ?
そして引数はクラスの外から飛んでくるんだろ?
だったら統一的に扱えるわけないじゃん

vector<X> vec;//お目当てのvector

for(vector<X>::iterator it = vec.begin(); it != vec.end(); ++it)
{
  (*it).func( /* ここに何か書けるか? */);
}

同じvectorに詰め込むのをやめて種類ごとのvectorを作った方がいいよ
それが嫌ならenum値返すメンバ関数作るなりRTTI使うなりして
派生クラスごとにif文書いてそれぞれの処理を書くことだ
どっちにしるfuncの名前は派生クラスごとに変えた方がいい
288デフォルトの名無しさん:2009/01/07(水) 02:34:39
効率無視してanyとfunctionでやってみた。2個の引数はpairでまとめた。3個以上必要ならtuple使えばいい。
あと、execからoperator ()にした。Cosはただの関数でも可能という例。
この例では、関数オブジェクトの戻り値型を実際の物にしたが、anyでも可。
#include <iostream>
#include <vector>
#include <utility>
#include <functional>
#include <cmath>
#include <boost/function.hpp>
#include <boost/any.hpp>
using boost::any;
using boost::any_cast;
int op_plus(int x, int y) {return x + y;}
double op_cos(double x) {return std::cos(x);}
struct Plus : std::unary_function<any const&, int> {
  int operator ()(any const& arg) const {
    std::pair<int, int> arg_pair = any_cast<std::pair<int, int> >(arg);
    return op_plus(arg_pair.first, arg_pair.second);
  }
};
double Cos(any const& arg) {
  return op_cos(any_cast<double>(arg));
};
int main() {
  std::vector<boost::function<any (any const&)> > vec;
  vec.push_back(Plus());
  vec.push_back(Cos);
  std::cout << "1 + 2 = " << any_cast<int>(vec[0](std::pair<int, int>(1, 2))) << '\n';
  double ret = any_cast<double>(vec[1](0.0));
  std::cout << "cos(0) = " << ret << std::endl;
  return 0;
}
289デフォルトの名無しさん:2009/01/07(水) 02:42:38
>>286
「〜とか〜でもいいです」なんて言われたら考えるのがあほらしい。
どうせ後出しの条件付けで「そうじゃないんです」って言われるに決まってる。
290デフォルトの名無しさん:2009/01/07(水) 03:05:42
やっぱboostきめぇな
291デフォルトの名無しさん:2009/01/07(水) 03:29:53
>>286
>vector内の隣りで実行完了したクラスの返却値をもらう

なんだ、隣のCosが返したdouble値を、Plusの自分の引数に渡してもいいんだ
じゃint維持にこだわる意味ないから、引数と戻り値の型を全部doubleにして
execを普通の仮想関数として書けば完全解決だな
よかったよかった

後からダメとか言うなよ
お前がよいですって言ってるんだからよいんだよな
よくよく考えて隣から返り値もらってもいいって書いたんだから間違いはないよな?
292277:2009/01/08(木) 00:00:44
>>288
ありがとうございます。
参考にして考えてみます。
>>287
1次元配列中でランダムに選ばれたセルでその近傍のセルの
情報を元に計算しなくてはいけないので、
vectorは分けれないのです。
>>289,291
自分でも要件がまとまっていない部分があって
変な質問になり、混乱させてしまい申しわけないです。
293デフォルトの名無しさん:2009/01/09(金) 00:00:58
BCC5.5でテンプレートを使った参照除去をやりたいんですが、通りません。あきらめるしかないのか?
template<typename T>
struct remove_refference{
  typedef T type;
};
template<typename T>
struct remove_refference<T&>{
  typedef T type;
};
294デフォルトの名無しさん:2009/01/09(金) 00:09:34
ほかのコンパイラを使えばいいじゃない。
295デフォルトの名無しさん:2009/01/09(金) 00:11:27
BCC5.5みたいなウンコンパイラを未だに使っている時点でアウト
296デフォルトの名無しさん:2009/01/09(金) 00:12:51
>>293
BCC6.1.0なら通る
コンパイラが古い
297デフォルトの名無しさん:2009/01/09(金) 00:24:44
g++でいいのに
Windowsで開発してる時点で負け組
298デフォルトの名無しさん:2009/01/09(金) 00:31:48
g++も古いバージョンはテンプレート悲惨だっただろ
299デフォルトの名無しさん:2009/01/09(金) 00:33:59
>>297
貴様はマックか?
300デフォルトの名無しさん:2009/01/09(金) 00:38:14
>>299
いやlinux
マカーの椰子はオブCマンセーなんかな
>>298
暗黒時代については文献も記憶もない
301デフォルトの名無しさん:2009/01/09(金) 01:00:29
g++はC++0x対応が遅そうなのが気がかり
302デフォルトの名無しさん:2009/01/09(金) 01:16:35
VC++切り捨てVC#のみサポートとかいう時代がきて大差なくなったり
303デフォルトの名無しさん:2009/01/09(金) 02:08:37
ネイティブを切り捨てるわけが無い
304デフォルトの名無しさん:2009/01/09(金) 02:27:21
>>296 6.1.0ってタダだっけ・・・?
305デフォルトの名無しさん:2009/01/09(金) 02:34:25
>>304
違うにきまってんだろカス
306デフォルトの名無しさん:2009/01/09(金) 13:04:01
文字列(std::string)の内容が数字だけ([0-9]+)であることを判別したい。
最も短く書ける方法は何でしょうか? BoostでもOK。
307デフォルトの名無しさん:2009/01/09(金) 13:18:01
つ[strspn()]
308デフォルトの名無しさん:2009/01/09(金) 13:23:25
strtolで返り値捨てて末尾の中身が'\0'かを見る程度で充分じゃないの。
309デフォルトの名無しさん:2009/01/09(金) 13:32:52
数字だけであることを判定するのと、longに変換してみるのは結果が違うと思う。
>306がどっちを要求しているか、だな。
310デフォルトの名無しさん:2009/01/09(金) 13:46:57
>>308
先頭の符号の判別は必要じゃない?
311306:2009/01/09(金) 13:53:46
>>307
std::strspn(s.c_str(), "0123456789") == s.size()

こうですか。なるほど。
strtolだと符号の判別等を無視してもこれより長いっぽいです。
312デフォルトの名無しさん:2009/01/09(金) 13:56:28
std::tr1::regex r("[0-9]+");
std::cout << (std::tr1::regex_match(str, r) ? "数字だけ" : "数字以外") << std::endl;
313デフォルトの名無しさん:2009/01/09(金) 14:11:41
だったら、一時バッファ1個使うだけの
sscanf(str.c_str, "%20[^0-9]", buf) == 0
とかでも充分じゃないかな。
↑は正しく動くか知らんけど。
314デフォルトの名無しさん:2009/01/09(金) 14:13:00
ていうかやっぱstrcspnの方が短くて楽だよな。
速度を求めるならisdigitでループだろうが。
315デフォルトの名無しさん:2009/01/09(金) 19:45:35
>>311
size == 0 の時も考慮に入れようぜ
316デフォルトの名無しさん:2009/01/09(金) 20:54:08
別の場所で
class hoge{〜〜}
って感じで定義されてるとして
class hoge* x

hoge* x
って同じだよね?
317デフォルトの名無しさん:2009/01/09(金) 21:01:10
同じ
ついでにstruct hoge* x;でもunion hoge* x;でも同じ
318デフォルトの名無しさん:2009/01/09(金) 21:25:08
>>317
どもです
319デフォルトの名無しさん:2009/01/10(土) 09:11:31
fgetsは処理ごとにメモリが動くので、一様な使い方ができません。
どのように切り抜けるか知っていますか。下記例。

#include<stdio.h>

int main(){
FILE *fp;
char a[256];
char *b[4];
char *c,*d;
int i;

if((fp=fopen("address.dat","r"))==NULL)exit(1);

c=fgets(a,256,fp);
printf("%s",c);
d=fgets(a,256,fp);
printf("%s",d);

fclose(fp);
}


これを
c=fgets(a,256,fp);
d=fgets(a,256,fp);
printf("%s",d);
printf("%s",c);

のような順序にすると同じ値が出てしまいます。(1行目が消えて、ファイルの2行目の出力になる)
320デフォルトの名無しさん:2009/01/10(土) 09:29:49
いったい何を切り抜けたいのかわからない・・・・
321デフォルトの名無しさん:2009/01/10(土) 09:36:58
そもそもaに格納してんじゃねーのかよ

c=fgets(a,256,fp);
d=fgets(a,256,fp);
printf("%s",d);
printf("%s",c);

ってやったら2回目のfgetsでaに入った値になるんじゃね?
格納場所はaなんだぜ
322デフォルトの名無しさん:2009/01/10(土) 11:21:14
アドレスはa==c==dだからな
そりゃあaが変わればcもdも一緒に変わりますよと。
323デフォルトの名無しさん:2009/01/11(日) 02:20:02
質問します。
クラスAのインスタンスを配列で1000個生成するのですが、
クラスAに、メンバ変数だけが含まれるのなら、
メモリ上には、メンバ変数×1000個のサイズの領域がほぼ確保されると思うのですが、

クラスAに、メンバ変数とメンバ関数が含まれる場合、
メモリ上には、メンバ変数×1000個+メンバ関数×1000個のサイズの領域が確保されてしまうのでしょうか?
それとも、メンバ関数は共通だから、メンバ変数×1000個+メンバ関数×1個のサイズの領域の確保で済むのですか?

教えてください。
324デフォルトの名無しさん:2009/01/11(日) 02:23:37
メンバ関数はインスタンスが保持するものではない。
メンバ関数はインスタンスを作らずとも存在し、常に1個だけ存在する。

ただし、仮想関数を作った場合、
各インスタンスは仮想関数テーブルと呼ばれるものへのポインタを持つ場合が多く、
その場合はポインタの分だけサイズが増える。
325323:2009/01/11(日) 02:34:01
>>324
ありがとうございました。迷ってしまいまして。すっきりしました。
326うどん:2009/01/11(日) 08:49:54
こんにちは、最近C言語と言うものに興味をもって始めようと考えていたのですが

「苦しんで覚えるC言語」というサイトを参照したところ始めるにあたって

「Borland C++ Compiler」という物が必要らしく 使うには登録も

必要だったので登録しました。しかしDL画面から何度試みてもDLできなくて

始める前からいきなりの壁にぶつかっていますorz

どなたか解決方法が分かる方がいましたら 教えて頂けないでしょうか?

スレのお題からは離れている気もしますが宜しくお願いしますm(_ _)m
327デフォルトの名無しさん:2009/01/11(日) 08:52:27
>>326
タダで使えるBorland C++ Part5
http://pc11.2ch.net/test/read.cgi/tech/1135127048/
328デフォルトの名無しさん:2009/01/11(日) 09:02:07
>>327

お早お返事ありがとうございます!

このページには教えていただく前に何度かたどり着いたのですが

このページのどのあたりからDLするかわからずに困っていました

厚かましいお願いなのですがそのあたりも教えていただけると

感謝の極みです。 

329デフォルトの名無しさん:2009/01/11(日) 09:04:39
>>328
分かったからもうこっちにはもどってこなくていいよ
330デフォルトの名無しさん:2009/01/11(日) 09:08:14
>>329

すみませんでした。。
331デフォルトの名無しさん:2009/01/11(日) 11:17:26
>>326
そんなダメサイトなんか見るからだよ。
332デフォルトの名無しさん:2009/01/11(日) 13:10:45
>>326
Cは楽しんで覚えるべきだと思うお。
333271:2009/01/11(日) 17:07:20
初心者にBC++勧めるのはどうなのかね。
とりあえずVC++の無料版使って、本腰入れてアプリとか作るようになったら有料版にするのが
一番お手軽かね。興味あったらググッて調べなさい >326

個人的にはKNOPPIXでgcc使うのが勉強になりそうな気もするけど。
334デフォルトの名無しさん:2009/01/11(日) 17:12:20
Cだったろ?
335デフォルトの名無しさん:2009/01/11(日) 17:35:18
VCから入るとほかで使えない人になっちゃうのがそれなりにいるからあんまり勧めたくない。
336デフォルトの名無しさん:2009/01/11(日) 17:46:33
vcのIDEが使えない人もどうかと
337デフォルトの名無しさん:2009/01/11(日) 17:56:22
makefileの書式とか忘れてるわ。
修正はたまにするけど新規で書けないな。
338デフォルトの名無しさん:2009/01/11(日) 18:38:02
それ俺だ >335
自分でmakefileとか拵える気にならない……
boost jamとかどうなのかな?
339デフォルトの名無しさん:2009/01/11(日) 18:47:46
俺はmakefileの方が楽だな
IDEはうまくいってるときはいいけど、トラブルがあった場合何もできない
340デフォルトの名無しさん:2009/01/11(日) 18:52:08
IDEだって独自形式のmakefileみたいなもんだ。
例えば、VC++のはvcbuildコマンドでビルドできるという具合。
341デフォルトの名無しさん:2009/01/11(日) 19:25:02
>>333
BCもBCB最新版を公開すれば、初心者に勧められるんだけどね。そうすればそのまま製品に移行する人も出てくるんだと思うんだよね。
342デフォルトの名無しさん:2009/01/11(日) 21:33:54
おまいら、g++忘れてるぞ
343デフォルトの名無しさん:2009/01/11(日) 21:55:34
おまいら、dmcも忘れてるぞ
344デフォルトの名無しさん:2009/01/12(月) 15:22:46
goto DMC;
345デフォルトの名無しさん:2009/01/12(月) 19:54:05
キモ
346デフォルトの名無しさん:2009/01/12(月) 20:57:51
申し訳ありません教えていただきたいです。環境はXPSP3 VC++2008です
giveio.cを使わせていただいてgiveio.sysをインストールしたいのですが
0x7c812aeb で初回の例外が発生しました: 0x000006F4: NULL 参照ポインタがスタブに渡されました。
Run-Time Check Failure #2 - Stack around the variable 'fullpath' was corrupted.
と言うエラーが出ます

/* #define MAX_PATH 256 */
static DWORD DriverInstall(LPCTSTR lpFname,LPCTSTR lpDriver)
{
BOOL dwStatus = 0;
SC_HANDLE hService = NULL;
char *address;
char fullpath[MAX_PATH];

/* connect to local service control manager */
if(OpenServiceControlManager())
return 1;

/* get full path of driver file in current directry */
GetFullPathName(lpFname,MAX_PATH,fullpath,&address);  ←ここのfullpathのようです

/* add to service control manager's database */
if ((hService = CreateService(hSCMan, lpDriver,
lpDriver, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, fullpath,
NULL, NULL, NULL, NULL, NULL)) == NULL)
dwStatus = GetLastError();
else CloseServiceHandle(hService);

return dwStatus;
}
コメントアウトにてMAX_PATH 256とありますが私の環境では260のようです
347デフォルトの名無しさん:2009/01/12(月) 21:20:10
 C++かどうかは知らないが、
NULLポインタのデリファレンスみたいだからポインタ変数を疑ったらいいと思う。
lpFname, lpDriver, hService, addressなど。
>>GetFullPathName(lpFname,MAX_PATH,fullpath,&address);
この関数の性質上、怪しいのは、lpFname, fullpath, addressであって、
assert(lpFname != NULL);でもいれとくといいかも。
TCHAR * address; TCHAR fullpath[MAX_PATH * sizeof(THCAR)];
GetFullPathName(lpFname, sizeof(fullpath), fullpath, &address)
とかなのか、Windowsは知らねぇよ、と最後にいってみる。

ここではなくて、Windows専用のところで聞いてみたらいい。
Win32API質問箱 Build75
http://pc11.2ch.net/test/read.cgi/tech/1231423602/
こんなところだっけ。
348デフォルトの名無しさん:2009/01/12(月) 21:48:32
>>347
ありがとうございます
lpFnameが不適切なptrなのとsizeof(fullmath)と置くことでデバッグできましたがやはり動作としておかしいようです
手動でインストールすることにします
349デフォルトの名無しさん:2009/01/13(火) 17:29:12
この度C++を勉強しようとしている者です。
レベルとしてはC#中級レベルくらいで、OOPは大体理解できています。

マのバイブルとされるEffectiveC++と、C++勉強用に独習C++を購入しようと思っていますが、

Effective C++ 【改訂第2版】

Effective C++ 原著第3版

この2種類があるみたいなんですが、どちらを買うべきなのでしょうか?
それとも両方買うべきなのでしょうか?
350デフォルトの名無しさん:2009/01/13(火) 17:32:51
>>349
今買うなら 第3版
351デフォルトの名無しさん:2009/01/13(火) 17:52:47
Effective C++ はほんと目から鱗の内容だな
すべてのC++プログラマは読んで身につけて欲しい
352デフォルトの名無しさん:2009/01/13(火) 17:57:32
>>350
古いの持ってるけど3版も買うべき?
353デフォルトの名無しさん:2009/01/13(火) 18:02:21
>>352
立ち読みでもして、欲しけりゃ買え。
3版の後ろの方に、2版との違いが載ってるから。
354デフォルトの名無しさん:2009/01/13(火) 18:17:55
>>350
ありがとう
355デフォルトの名無しさん:2009/01/13(火) 22:42:38
>>349
禿本は却下?

     /⌒\
    川 ´∀`||
    ||||  川 |||
356デフォルトの名無しさん:2009/01/13(火) 22:44:59
std::tr1::bind 使おうとしたら _1 が定義されてないとエラーが出てしまいました
boost ライブラリ入れてない状態だと、tr1::bind の _1 とかって使えないのですか?
357デフォルトの名無しさん:2009/01/13(火) 22:49:07
>>356
std::tr1::placeholders名前空間に入っている。
358デフォルトの名無しさん:2009/01/13(火) 23:07:12
なんで66立ったんだ?
359デフォルトの名無しさん:2009/01/13(火) 23:08:29
前にもどっかのスレでそういうことがあった気がする。
360デフォルトの名無しさん:2009/01/13(火) 23:13:14
>>357
ありがとうございます。
361デフォルトの名無しさん:2009/01/14(水) 21:09:52
http://d.hatena.ne.jp/MaD/20081202

これ、最後がどうしてbar/fooと出力されるのでしょうか?
362デフォルトの名無しさん:2009/01/14(水) 22:02:21
>>361
gccは(整数)+(ポインタ)の式をポインタ→整数の順に評価するから
363デフォルトの名無しさん:2009/01/14(水) 22:03:21
>>362
なるほど!361じゃないけどありがとうございました。
364361:2009/01/14(水) 22:36:04
361はまだわからない・・・
365デフォルトの名無しさん:2009/01/14(水) 22:46:54
A + B は、GCC では最適化が効かなければ、
A と B が数値の場合は A → B の順に、
A か B のどちらかがポインタの場合はポインタが先に評価される、
ということだろう。

実際には最適化が効くと結果が変わるかもしれないし、
処理系によって結果も違うだろうし、
あまり覚えても意味は無い事だな。
処理系作るなら必要な知識かもしれないが。
366デフォルトの名無しさん:2009/01/14(水) 23:12:54
cygwinのgcc3.4.4でも確かにそうなるね

(int) puts("foo") + (int *)puts("bar");

で bar foo と出る
面白いけど、規格上は不定だろうし、とりたて役にはたたないな
367デフォルトの名無しさん:2009/01/14(水) 23:15:37
副作用完了点でないところで何らかの結果を出そうとしている時点で鼻から精液が出てもおかしくないね。
368デフォルトの名無しさん:2009/01/14(水) 23:32:03
評価順なんぞに依存した処理を書いても大体ロクなことにならないからな
369デフォルトの名無しさん:2009/01/14(水) 23:44:27
barfooと出てもfoobarと出てもfboaorと出てもおかしくないわけだ。
370デフォルトの名無しさん:2009/01/15(木) 00:02:53
フボアオー
371デフォルトの名無しさん:2009/01/15(木) 00:09:16
fboaorと出ることはないだろ
puts("foo")とputs("bar")の処理が混ざらないことは保証されるはず
372361:2009/01/15(木) 00:09:32
>>365

ようやくわかった。
さんくす。
373デフォルトの名無しさん:2009/01/15(木) 19:05:09
アドバイスお願いします。
今ゲームを作ろうとしていて、町のデータに int int int double double の数値を予定しています。
こういった場合、 町のデータっていうものは クラスまたは構造体にした方がいいんでしょうか?

現在、クラスが良く判っていない為、配列であてているのですが、町(データ)の数が増えた場合、クラス化してあると管理は楽になりますか?
スレ違いだったらごめんなさい
374デフォルトの名無しさん:2009/01/15(木) 19:19:22
>>373
やりようによるとしか・・・・・
クラス使ってもアホがやると、やっぱりゲログチョに・・・・・・
375デフォルトの名無しさん:2009/01/15(木) 19:21:36
 データだけであるのなら、構造体(メンバ関数無しのね)にするのがいいと思う。それをクラスに持たせる形にする。
アライメントや型サイズに気を配りながら、バイナリで構造体をファイルに吐いたりファイルから食ったりする。

とりあえず、こっちで聞いた方がいいと思うよ。
ゲームにおけるデータ構造・クラス設計・パターン2
http://pc11.2ch.net/test/read.cgi/gamedev/1211544659/
376デフォルトの名無しさん:2009/01/15(木) 19:54:20
std::istreamのようなインターフェースから一文字ずつget()出来る場合、
配列strに含まれない文字からなる配列retを返す賢い方法はありますか?
言い方を変えると、strに含まれる文字が来るまでget()し続けるということです。
algorithmヘッダは使えます。
377デフォルトの名無しさん:2009/01/15(木) 19:57:32
unget とstrchr でいいんじゃねーの
賢いかは知らん
378デフォルトの名無しさん:2009/01/15(木) 20:09:11
unget()は、一文字だけ常に返せることが保証されていると考えていいんですか?
putback()が一文字以上はエラーになる場合とならない場合があって、
実際のクラスとストリームオブジェクトの状態に依存するようで
どうにも困ってます。
ストリームがエラー状態になった場合の回復方法もよくわからない。
難しすぐる。
379デフォルトの名無しさん:2009/01/15(木) 20:09:16
>>374,375
回答ありがとうございます。
紹介してもらったスレ読んで見てきます
380デフォルトの名無しさん:2009/01/15(木) 21:23:40
>>375
現行スレをざっと見てきたのですが、今の私では・・ って感じでした。
クラスの中に構造体を所持すればいい? というのはどういう感じなのでしょうか?

データクラス (町) {構造体 <町データ> } なのかなぁ
クラス = 構造体+関数 って認識なんですが、 根本間違えてる? 
381デフォルトの名無しさん:2009/01/15(木) 22:39:07
>>380
構造体にしろクラスにしろPOD型(intとか)に限らずクラスや構造体をメンバにできる。
町データをどうするべきかは>>375に貼られてるスレで訊くべし。
382デフォルトの名無しさん:2009/01/16(金) 00:47:19
>>376
get() の繰り返しを行う Iterator をでっち上げて remove_copy_if() 。
383デフォルトの名無しさん:2009/01/16(金) 01:39:54
>>382
そんなイテレータを作らなくてもistreambuf_iteratorで十分という気がする。
384デフォルトの名無しさん:2009/01/16(金) 01:44:07
>>383
「std::istream から」と書いてあればそうなんだけど、「のようなインターフェースから」と
書いてあるからたぶん実際は違うんだろうなと思った。
385デフォルトの名無しさん:2009/01/16(金) 07:15:41
int8_t num = 10;
cout << num;

上記でint8_tを表示できないのですがなぜでしょうか?
intにキャストすると表示できます。
386デフォルトの名無しさん:2009/01/16(金) 07:20:00
通常はint8_tはcharのtypedefで
通常はcoutにcharを出力すると文字として表示されるようになっているから
387デフォルトの名無しさん:2009/01/16(金) 07:24:34
signed char じゃね。
まあ同じ事だけど。
388385:2009/01/16(金) 07:33:16
>>386,387
なるほど。どうもありがとうございました。
389デフォルトの名無しさん:2009/01/16(金) 16:07:00
http://www001.upp.so-net.ne.jp/isaku/rand.html

ここに載ってある

static long x=S;
int rand() { x=x*A+C; return(int)(x>>16)&32767; }
void srand(long s) { x=s; if (F) rand(); }

A=214013, C=2531011, F=0, S=1。

というのですが if(F)ってどういう意味ですか?
F=0になると何も起こらない気がするのですが
390デフォルトの名無しさん:2009/01/16(金) 16:24:40
>>389
BC++とそれ以外の動作の違いをifで吸収して説明しているだけだよ。
srandを呼んだときに、乱数を1回分捨てるかどうかの違い。
アルゴリズムの本質的な部分ではないから、まとめている。
391デフォルトの名無しさん:2009/01/16(金) 17:45:38
テンプレートでグローバルなキャスト演算子って書けましたっけ?書き方が分からんのですが・・・
392デフォルトの名無しさん:2009/01/16(金) 17:59:11
#ifndef GLOBAL_CAST_HPP
#define GLOBAL_CAST_HPP

namespace mycast{

template <typename _ResultType,typename _T>
_ResultType global_cast(const _T& in){
 return _ResultType(in); // 処理は適当に
};

}

#endif

ていうか、結局何がしたいの?
393デフォルトの名無しさん:2009/01/16(金) 18:07:56
は?
394デフォルトの名無しさん:2009/01/16(金) 18:12:06
関数でなくて演算子オーバーロードが良いんですが・・・
やりたいのはbad_castを捕まえて自前のエラーを投げることと、一部の型について特殊化を行うためです。
395デフォルトの名無しさん:2009/01/16(金) 18:21:04
cast演算子は確かオーバーロード出来ないので、適当に関数組んで中で処理させるしかない。
c++0xではオーバーロード出来るようにしたいねとか話題があったような気もするけど、結局どうなったのかは知らない。
396デフォルトの名無しさん:2009/01/16(金) 18:53:30
>>390
さんくす、最初の一回を捨てるということかな
397デフォルトの名無しさん:2009/01/16(金) 19:40:51
srandは種を入れる関数だったね
srandで呼び出すのかと間違ってました・
398デフォルトの名無しさん:2009/01/16(金) 20:52:08
ここで言っているキャスト演算子って何?
static_cast とか?それとも (Type) みたいなキャスト表記?
bad_cast を捕まえてっていうからには dynamic_cast に被せるんだろうけど
だったら >392 で十分な気がするんだ。
399デフォルトの名無しさん:2009/01/16(金) 20:55:28
>>398そうですね。どうやら無理っぽいのでキャスト関数に落ち着きます。ありがとうございました。
400デフォルトの名無しさん:2009/01/16(金) 23:14:20
static_cast にこだわんなくても
hogehoge_cast でええやん。
401デフォルトの名無しさん:2009/01/17(土) 18:08:07
TCHAR *pBuf = new TCHAR[iLength+1];
edit.GetLine(i,pBuf);
pBuf[iLength+1] = 0;
str.Format(_T("%s\r\n"),pBuf);
//ファイルへ書き込み
ar.WriteString(str);
delete[] pBuf;
というコードを実行させるとdelete[]でエラーをはいてしまうんですがなぜでしょうか?
402デフォルトの名無しさん:2009/01/17(土) 18:11:39
>>pBuf[iLength+1] = 0;
ぶっ壊してるじゃないか
403デフォルトの名無しさん:2009/01/17(土) 18:12:35
>>401
iLength + 1しか確保していないのにiLength + 1番目に書いちゃダメ。
それが原因かはしらね。
404デフォルトの名無しさん:2009/01/17(土) 18:16:17
pBuf[iLength] = 0;
にしたらdelete[]でエラーをはかなくなった代わりに、文字が全て不定値になりました。。。
405デフォルトの名無しさん:2009/01/17(土) 18:21:52
iLength + 2 確保するという発想はないのだろうか
406デフォルトの名無しさん:2009/01/17(土) 18:24:14
そもそもMFCならCStringに直接入れられるんじゃないだろうか。
つーか、EditControlなら複数行まとめて取り出せるんじゃないだろうか。
いずれにしても、スレ違いになるが。
407デフォルトの名無しさん:2009/01/17(土) 18:29:43
+2しても全て不貞値になりましたとさ・・・もう疲れたよ派とラッシュ・・・
ありがとうございました
408デフォルトの名無しさん:2009/01/17(土) 18:37:14
ttp://msdn.microsoft.com/ja-jp/library/7775836w.aspx
MFC使ったこと無いからよくわかんないけど、
edit.GetLine(index.buf,sizeof(buf));
って書けって言ってるような気がしなくも。
見当違いならごめんね。
409デフォルトの名無しさん:2009/01/17(土) 18:42:39
実際にはバイト数じゃなくて文字数だった気がするよ。
410デフォルトの名無しさん:2009/01/17(土) 19:15:06
>>407
GetLineの戻り値は何になってる?
411デフォルトの名無しさん:2009/01/18(日) 01:56:50
>>401
iがiLengthよりうんと大きい値になっているということはない?
412デフォルトの名無しさん:2009/01/18(日) 15:56:21
>>404
「不定値」とは具体的にどのようなものですか?
コンパイラあるいはデバッガに「文字列は不定値です」と言われたのですか?
413デフォルトの名無しさん:2009/01/18(日) 23:03:10
質問させていただきます
vecter<ObjectA> vec;
vec.push_back(new ObjectA);
としてvecterに複数個オブジェクトを入れた場合、
最後にdeleteするのは一般的にどうやるのが普通なのでしょう?
vec.clear()ではオブジェクトのデストラクタも呼ばれないので・・・
414デフォルトの名無しさん:2009/01/18(日) 23:05:21
boost が使えるなら boost::ptr_vector<ObjectA> を使うなり
std::vector< boost::shared_ptr<ObjectA> > を使うなりする。

boost が使えないなら、
vec を、必ず vec を制御する関数を通して扱うか、
カプセル化してしまう。
415デフォルトの名無しさん:2009/01/18(日) 23:12:45
Boostがだめでもstd::tr1::shared_ptrという希望がある。
416デフォルトの名無しさん:2009/01/18(日) 23:26:04
一般的かは知らないけど、下のような関数作っておくというのも一つ。
コンテナでも配列でも使えて便利。

template<class Itr> void purge(Itr begin, Itr end) {
while(begin != end) {
delete *begin;
*begin = 0;
++begin;
}
}
417デフォルトの名無しさん:2009/01/18(日) 23:29:14
for_each + checked_deleterでいいじゃない。
っていうか例外投げられたらリークする。
418デフォルトの名無しさん:2009/01/19(月) 03:40:56
deleteが例外投げちゃいかんでしょ
419デフォルトの名無しさん:2009/01/19(月) 04:02:25
>>418
そうではなくて、purgeを呼ぶ前に例外投げられたら駄目だろという一般的な話。
420デフォルトの名無しさん:2009/01/19(月) 04:09:15
>>415
今までさわってきた限りだと、boostもtr1も入ってないか、boostしか入ってない処理系にしか出会わなかった。
tr1ってまだ普及してないんだなって思った。
421デフォルトの名無しさん:2009/01/19(月) 19:00:10
ためしに416
をしてみたらなぜか無限ループから抜け出せなくなったw
422デフォルトの名無しさん:2009/01/19(月) 19:48:26
>>416
イテレーターの参照を直接deleteしたらまずくないか?
423デフォルトの名無しさん:2009/01/19(月) 21:48:31
ポインタのコンテナなんだろ
424デフォルトの名無しさん:2009/01/19(月) 22:01:57
vectorの削除って
for(int i=0;i<vector.size();i++)
{
delete vector[i];
}
じゃぁだめなんでしょうか?
425デフォルトの名無しさん:2009/01/19(月) 22:03:04
いいけど、他のコンテナに変更した時に書き直さなきゃならなくなるよ。
426デフォルトの名無しさん:2009/01/19(月) 22:05:16
VC++で作成したライブラリを
gccでコンパイルしたいんだけど
できるものですか?

マングリングとかの関係で云々という記述は見たりするのだけど・・・
427デフォルトの名無しさん:2009/01/19(月) 22:10:00
フルコンパイルする分には問題ないよ。
ただ、VC++ に依存するコードがあると移植作業が必要だけど。
428デフォルトの名無しさん:2009/01/19(月) 22:10:49
コンパイルだけなら、環境依存なコードじゃなければ問題ない
VCでビルドしたスタティックライブラリをgccでリンクとなると無理
理由は名前マングリングなどバイナリの互換性が無いから
429デフォルトの名無しさん:2009/01/19(月) 22:15:41
>>427,428
レスありがとうございます.

そうですかー,ソースは自分のじゃないので手元にない
というわけで,無理ってことですね

reimpとかdlltoolとかで変換できればいいんですけどねー,残念です
430デフォルトの名無しさん:2009/01/19(月) 22:28:17
VC++ライブラリを呼び出すextern "C"のラッパーを(VC++で)作って
それをgccで呼び出すようにすれば行けるんじゃないかな
やったことないけど
431デフォルトの名無しさん:2009/01/19(月) 22:31:45
そうそう、__cdeclリンケージのライブラリであれば問題なし
C++のスレで質問するってことは違うんだろうけど
432デフォルトの名無しさん:2009/01/19(月) 22:34:35
あるいはWindowsなら、純粋仮想関数のみの抽象クラス(仮想デストラクタなし)でも相互に行けるはず。
ようするにCOM一歩手前。
当然COMインタフェース化してもいい。
433デフォルトの名無しさん:2009/01/19(月) 22:34:40
>>430
マングリング以外の部分でマズいこと起きそうな気がする。
434デフォルトの名無しさん:2009/01/19(月) 23:19:12
>>430-433

一応reimpにはかけていて
ライブラリ中のclassで記述されている部分が軒並み変換されなくて
どうにかならないかと思って 調べている最中なのです

非純粋仮想関数のclassを使っている時点でNGという認識であってますか?


435デフォルトの名無しさん:2009/01/19(月) 23:28:45
VC++ だとメンバ関数ポインタは多重継承や仮想継承をしてるかによって
4、8、12バイトと可変だが、g++ だと8バイト固定だったりする。
this ポインタの渡し方も VC++ だと ecx 渡しだけど g++ だと eax 渡し。
本当に色んな部分で決定的に違うから、C++ は簡単に変換できないと思われ。
436デフォルトの名無しさん:2009/01/19(月) 23:30:06
VC++ で C の dll を作って、
それを g++ で使えるようにするといいんじゃない?
437デフォルトの名無しさん:2009/01/20(火) 00:16:05
クラスを直接受け渡すのは無理だろうな
面倒だがPOD構造体に直してから渡して受け取った方で再構築するしかない
438デフォルトの名無しさん:2009/01/20(火) 01:10:22
>>435-437
ありがと,明日ってか,今日色々試して見ます
439デフォルトの名無しさん:2009/01/21(水) 01:35:07
440デフォルトの名無しさん:2009/01/21(水) 10:43:26
呼び出される関数が予めオーバーライドされた物かどうか判断する合法なやりかたってありますか?
struct Hoge{
virtual ~Hoge(){}
void virtual X(){}
void fuga(){/*ここでどちらが呼ばれるか判定*/}
};
struct Piyo:public Hoge{
void X(){}
};
441デフォルトの名無しさん:2009/01/21(水) 10:46:45
>>440
できてもあんまりうれしくないから、無いと思うよ。
そんな判別ができたとして何がしたいのかわからん。
442デフォルトの名無しさん:2009/01/21(水) 10:51:21
子クラスの面倒を見たいんです・・・
443デフォルトの名無しさん:2009/01/21(水) 10:52:57
>>440
if(Hoge::X == this->X)
とかやったらわかるだろうか。試してないし保証しないが。
なんにせよそんな判断がしたい、ってのが変な話なような。
444デフォルトの名無しさん:2009/01/21(水) 10:54:06
そうなると↓こっちのスレで聞くのがいいかもね。
http://pc11.2ch.net/test/read.cgi/tech/1187922645/
445デフォルトの名無しさん:2009/01/21(水) 11:00:13
>>443
Hoge::X の時点でコンパイルできないね。メンバ関数へのポインタなら &Hoge::X だけど、
&this->X もコンパイルできない。

&this->X に対する gcc 3.4 のエラー。
> error: ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say `&Hoge::X'
446デフォルトの名無しさん:2009/01/21(水) 11:49:11
>>440
RTTI有効にしてインスタンスが何なのか調べればいいんじゃね?
447デフォルトの名無しさん:2009/01/21(水) 12:08:25
typeid(*this) != typeid(Hoge)ですか?コストはどうなんでしょう・・・
448デフォルトの名無しさん:2009/01/21(水) 12:29:51
親クラスの中で派生クラスでの挙動を考えるというのは
何と言うか構造的に問題がありそう気がするけども
449438:2009/01/21(水) 22:12:45
昨日今日で色々試したけど,駄目でした

extern"C"でのラッパを作って一見いけてそうに見えたんだけど
実行すると何も吐かずにエラーっぽく落ちる
450デフォルトの名無しさん:2009/01/21(水) 22:27:20
なんかそれは別の理由っぽいが
451デフォルトの名無しさん:2009/01/21(水) 23:28:32
>440
型によって処理を切り替えたいのならその部分から仮想関数にすればいいじゃないか。
452デフォルトの名無しさん:2009/01/21(水) 23:38:25
>>451
その更に前後に処理挟みたいんですよね。用はBeginPaintとEndPaintで挟みたいってことなんですが・・・
453デフォルトの名無しさん:2009/01/21(水) 23:40:36
NVIの出番だな
ぐぐれ
454438:2009/01/21(水) 23:59:58
>>450

printfの間にラッパ関数を呼び出したら何も表示されなくて
関数外したら表示されるから,ラッパの所為かと思ってたけど
違うとなると....なんだろうか...
455デフォルトの名無しさん:2009/01/22(木) 00:01:11
なんだろうかとかいわれても・・・・・・・
456438:2009/01/22(木) 00:23:47
ラッパの作り方が悪いとかで,
関数コール時に不正な処理をしているのかと想像していたんだけど
もう少し仕込みを入れて調べてみます
457デフォルトの名無しさん:2009/01/22(木) 00:44:18
XをprivateにしてXを呼び出すメンバ関数を作ってそこの前後にbeginとend呼べば。
継承したクラスで呼びたくないならその関数もラップしる。
458デフォルトの名無しさん:2009/01/22(木) 10:51:24
type erasure について詳しく載ってるサイトまたは書籍教えてください。
できれば日本語で..
459デフォルトの名無しさん:2009/01/22(木) 23:26:45
少しは検索しろよ。紹介する気にもならん
460デフォルトの名無しさん:2009/01/23(金) 00:01:16
結局サンプルコードを自分で作って試したら
やり方はあってて,実行時にdllがありなかっただけでした
すんません
ってことで,無事解決できました.ありがとうございました.
461438:2009/01/23(金) 00:02:12
あっ,名前忘れた
460は自分です
462デフォルトの名無しさん:2009/01/23(金) 00:19:19
463デフォルトの名無しさん:2009/01/23(金) 17:10:46
>>459
ごめんなさい
464デフォルトの名無しさん:2009/01/24(土) 07:31:10
すれ違いな気もするけど、C言語使っての上でと言うことで…

実験とかで得たデータを保存するとき、
独自フォーマットよりは、汎用のが良いと思っています。
XML,YAML,CSV…変わったところでXとか、まぁいろいろありますけど、
Cで"繰り返しの中に繰り返しが入るような"データを保存するとき、
どのような形式が向いていますか?
(たとえば、SGML系は配列等には向かないと思うのです)
465デフォルトの名無しさん:2009/01/24(土) 09:27:38
Cかどうかはさておき
ネストの深さが不定ならxml, yamlかなあ
ネストが親要素で固定されるならなんでもいいんじゃね?
466デフォルトの名無しさん:2009/01/24(土) 09:49:22
あとJSONとか?
CSVで扱える構造なようならCSVが扱いやすいと思うけど
467デフォルトの名無しさん:2009/01/24(土) 12:37:36
>>464
ASN.1でいいだろ
468デフォルトの名無しさん:2009/01/24(土) 13:18:16
そこで独自フォーマットを作ってこそのプロなんだと思うが。
469デフォルトの名無しさん:2009/01/24(土) 13:29:32
何のプロ?
車輪の再発明なんてド素人中のド素人だろ。
470デフォルトの名無しさん:2009/01/24(土) 13:48:43
独自フォーマット作るぐらいなら、S式使った方がよっぽどマシだよ。

話の流れをぶった切って(ry
こんなの作っているんだけど、M0がvoid式だとコンパイルエラーになります。
何か上手い回避方法ありませんか?
SFINAEやろうとしても戻り値がvoidかどうかは判別できないし……

template<typename H, typename M0, typename A1>
static bool entry() {
 struct Local {
  static H trampoline(M0& method, A1& arg1) {
   return H(method(arg1));
  };
 };
};
471デフォルトの名無しさん:2009/01/24(土) 14:43:02
>>470
うまい方法って具体的に何?
M0がvoid関数だった場合、entryは何を返したいの?
472デフォルトの名無しさん:2009/01/24(土) 14:51:57
void式の時はH()を返そうかと思います。
473デフォルトの名無しさん:2009/01/24(土) 14:53:50
VC++ってどうしてliteralが青く光るのはなんでなのは何故に?
474デフォルトの名無しさん:2009/01/24(土) 15:46:54
>>470
これが最適だとは思えないが、
M0をvoidでテンプレートの部分特殊化すれば
出来ることは出来る。
475デフォルトの名無しさん:2009/01/24(土) 16:25:22
>>473
目が悪いんじゃないか? 青く光ってなんかいないぞ。
476デフォルトの名無しさん:2009/01/24(土) 16:54:48
>>473
C++/CLIでキーワードになっているから。
477デフォルトの名無しさん:2009/01/24(土) 17:57:56
>470
関数テンプレートなんで、部分特殊化はムリ……
とりあえずテンプレート引数を一つ増やして何とかしました。格好悪いけど。
template<typename H, bool return_value, typename M0, typename A1> struct filter1 {
 static H trampoline(H& method, H& arg1) { return method(arg1); };
};
template<typename H, typename M0, typename A1> struct filter1<H, false, M0, A1> {
 static H trampoline(H& method, H& arg1) { method(arg1); return H(); };
};
public:
template<typename H, bool return_value, typename M0, typename A1>
static bool entry() {
 struct Local {
  static H trampoline(M0& method, A1& arg1) {
   return filter1<H, return_value, M0, A1>::trampoline(method, arg1);
  };
 };
};
478デフォルトの名無しさん:2009/01/24(土) 18:30:42
まあ、なんだ。
あんまり無理はするなよ。
479デフォルトの名無しさん:2009/01/24(土) 20:36:18

Winnyの情報流出を管理・指導する国のIPA職員 岡田賢治 主任が違法ファイルDLしまくり感染して流出したドキュメント類。
嫁以外の女とのエッチ写真や、幼女児童ポルノ、違法アプリ所持、違法アプリバラ蒔き証拠など大量に流出。

★郵政省(今の総務省)、日立製作所、博報堂、味の素・・・と凄い流出規模!
http://ruru2.net/jlab-ruru/s/ruru1232764892388.jpg
★本人は著作権無視で違法ファイルダウンしまくりのくせに、著作権を勉強して知的所有権管理資格持ってるw
http://ruru2.net/jlab-ruru/s/ruru1232767964337.jpg
★全契約先でこの契約書結んでいるが、秘密保持、情報返還・処分義務の立派な契約違反。
http://ruru2.net/jlab-ruru/s/ruru1232767993881.jpg
★西武百貨店社員6155名分の個人情報を違法に自宅に持ち帰り流出。
http://ruru2.net/jlab-ruru/s/ruru1232768015222.jpg
★楽天ショップから個人情報データを違法に自宅に持ち去り大量に個人情報流出!
http://ruru2.net/jlab-ruru/s/ruru1232768041252.gif
★大量のソニーやマイクロソフト等の大手企業勤務者の流出個人情報! 自民党とか衆議院とかもある。
http://ruru2.net/jlab-ruru/s/ruru1232768065918.gif
★IPAは自身の流出は画像しか無いと断言しているが大嘘で、IPA役員資料とかも流出している。(IPA資料を無断で自宅に持ち帰り)
http://ruru2.net/jlab-ruru/s/ruru1232768123179.jpg
★三井リハウス(株)の入居者の口座番号や入金金額等のデータベースもIPA岡田賢治主任が流出
http://ruru2.net/jlab-ruru/s/ruru1232768311436.gif

国の情報処理推進機構 IPA専門職員として違法アプリばら蒔きの大問題犯罪証拠も流出。
違法アプリやシリアルキーを周囲にわざとバラ蒔いている。(現在も違法ATOKを使用しており、長年違法アプリを日常的に使用していた可能性大)

★Micro Soft VisualC++の違法シリアルキーを知人に教えたメール
http://ruru2.net/jlab-ruru/s/ruru1232768092277.jpg
★メールソフトRimArts社 Beckyの違法シリアルキー等、内容から見ても長年かなり広範囲にバラ蒔いていたようだ
http://ruru2.net/jlab-ruru/s/ruru1232768242947.jpg
480デフォルトの名無しさん:2009/01/24(土) 20:36:41

仁義なきキンタマ ウイルス情報 Part80
http://changi.2ch.net/test/read.cgi/download/1229742858/546
546 :[名無し]さん(bin+cue).rar :sage :2009/01/04(日) 00:24:59
報告する時は、詳しく的確に、一部だけ報告しないでお願いね

[殺人] Administrator(20081230-101522)のキンタマ.zip 2,263,376,860 09ed98f10653c3fc2555621ceeed6bc33e8f6228
[殺人] Administrator(20081230-101522)のメール.zip 59,426,579 4da9459b30eec31f58b86530dbb48d1cf86ef4be
[写真集][IV] Administrator(20081230-101522)のアルバム.zip 2,205,946,474 9d87cc0e08dc0e3afd959fcead6c48d569787cee

膨大な量のファイル数キンタマ ファイル数 13508 フォルダ数2381
以前勤めてた会社の資料など多数 独立行政法人情報処理推進機構などの資料など無いと思うが
有るかも知れない、あまりにも数が有り過ぎる、メールなどは、古いものばかりメルマガなど膨大な量
個人情報などは、披露宴主席者などの住所、名前、電話、メール 数十人分しかしエロばっかり落としてるな
ちなみに ハメ撮りscr 踏んだみたいね

早稲田実業学校中等部卒業
早稲田実業学校高等部卒業
早稲田大学政治経済学部政治学科卒業
卒論「知的財産権とインターネット技術」
当時の同大学理工学大学院の大川功 賞佳作を受賞
コンピュータ関連会社に入社ソフトウェア開発の仕事を経て
2005年に独立行政法人情報処理推進機構に入社
ソフトウェア・エンジニアリング・センター企画グループに配属
同グループ主任 岡田賢治さん33歳
481デフォルトの名無しさん:2009/01/24(土) 20:37:03

IPA職員 岡田賢治 主任の報道記事まとめ【1】

★NHK
http://s02.megalodon.jp/2009-0105-1642-01/www3.nhk.or.jp/news/t10013365941000.html
★IPA職員が情報流出 ― 私物パソコンでファイル交換ソフトを使用(RBB TODAY) - Yahoo!ニュース
http://s03.megalodon.jp/2009-0105-1955-03/headlines.yahoo.co.jp/hl?a=20090105-00000007-zdn_ep-sci
★IPA職員Winnyでファイル流出&嫁のブログ祭り - 探偵ファイル
http://www.tanteifile.com/newswatch/2009/01/05_01/index.html
★IPA職員がファイル交換ソフトでウイルスに感染、写真など流出 - ネットwatch
http://internet.watch.impress.co.jp/cda/news/2009/01/04/21994.html
★情報流出対策職員“赤恥”…自身半裸写真など流出 - zakzak
http://www.zakzak.co.jp/top/200901/t2009010510_all.html
★IPA職員がまさかの情報流出 - 「Share」の可能性も「現在本人に確認中」 - マイコミュ
http://journal.mycom.co.jp/news/2009/01/05/004/
★J-CASTニュース(情報セキュリティ専門家のはずのIPA男性職員の失態)
http://www.j-cast.com/2009/01/05033141.html
★時事通信社ニュース(古いソフトを探すためと、本人の虚偽と分かるコメント有り!組織ぐるみで隠蔽工作開始か?)
http://www.jiji.com/jc/c?g=soc_30&k=2009010500683
★CNET JAPAN わいせつ画像や児童ポルノ動画、違法かな漢字ソフトをダウンロード--IPA職員
http://japan.cnet.com/news/sec/story/0,2000056024,20386070,00.htm
★CNET JAPAN 「IPAとして慙愧に堪えない」--仲田理事が会見で職員の情報流出事件を説明
http://japan.cnet.com/news/sec/story/0,2000056024,20386085,00.htm
★IPA プレス発表 当機構職員のパソコンによる情報流出について
http://www.ipa.go.jp/about/press/20090106.html
★INTERNET WATCH  IPAが職員の情報流出で記者会見。
 昨日の組織ぐるみ隠蔽工作から、2ちゃんねらーの追撃で違法ファイルの使用と児童ポルノ動画を一転して認める!。
http://internet.watch.impress.co.jp/cda/news/2009/01/06/22018.html
482デフォルトの名無しさん:2009/01/24(土) 20:37:24

IPA職員 岡田賢治 主任の報道記事まとめ【2】

★毎日.jp わいせつ画像やかな漢字ソフトをダウンロード--IPA職員、ファイル交換ソフトで
http://mainichi.jp/life/electronics/cnet/archive/2009/01/06/20386070.html?link_id=RLD03
★@IT IPA職員のPCからの情報流出、事実関係を説明
http://www.atmarkit.co.jp/news/200901/06/ipa.html
★IT PRO IPA職員がファイル交換ソフト利用で、個人情報含む1万6000件を流出
http://itpro.nikkeibp.co.jp/article/NEWS/20090106/322322/
★マイコミジャーナル IPA職員の情報流出で緊急会見 - 前職時代の取引先企業情報など1万件超
http://journal.mycom.co.jp/news/2009/01/06/055/
★探偵ファイル IPA流出騒動職員の妻、不正転売と薬事法違反疑惑
http://www.tanteifile.com/newswatch/2009/01/06_01/index.html
★live doorニュース 「指導する側」のIPA職員がWinnyでウイルス感染、個人情報が流出。
http://news.livedoor.com/topics/detail/3962545/
★秒間SUNDAY IPA職員がファイル交換ソフトでウイルス感染!エッチ後画像など大流出
http://www.yukawanet.com/sunday/2009/01/ipawinny.html
★楽天(ショップ) IPA職員のパソコンによる情報の流出について
http://www.rakuten.co.jp/stellina/946713/
★西武百貨店 IPA職員のパソコンによる当社の情報の流出について(IPAに怒り爆発w)
http://www2.seibu.co.jp/common/images/pdf/20090107.pdf
★探偵ファイル ポエムに企画書…IPA職員の情報流出事件続報!
http://www.tanteifile.com/newswatch/2009/01/07_01/index.html
★探偵ファイル IPA騒動に急展開、驚愕の流出情報の数々
http://www.tanteifile.com/newswatch/2009/01/08_01/index.html
★ZAKZAK 流出事件のIPA職員ばかりか妻は薬事法に違反★
http://www.zakzak.co.jp/top/200901/t2009010701_all.html
★つこうたIPA職員 チャイルドポルノコレクターだった
http://www.technorati.jp/post/1S_jIJkf5a8hD3fMmxghB%2BYuGJfDPiYu%2BYizu8vv1oY%3D
483デフォルトの名無しさん:2009/01/24(土) 20:37:47

IPA職員 岡田賢治 主任の報道記事まとめ【3】 アサヒ芸能 週刊誌に岡ちゃんと純子と仲良く掲載
※違法アプリ、変態幼女児童ポルノ等のダウンを認めながら、給与支給の停職3カ月と国民を馬鹿にした処分!

★探偵ファイル IPA流出事件職員の妻の転売業者、薬事法違反が確定★
http://www.tanteifile.com/diary/2009/01/08_02/index.html
★アサヒ芸能 週刊誌 ネット情報セキュリティ相談窓口職員の裸画像が流出 恥写真!&島○純子も
http://ruru2.net/jlab-ruru/s/ruru1232772605296.jpg
★IPA職員に停職3カ月の懲戒処分 「Winny」「Share」情報流出で
http://www.itmedia.co.jp/news/articles/0901/19/news085.html
★情報流出のIPA職員、停職3カ月の懲戒処分
http://internet.watch.impress.co.jp/cda/news/2009/01/19/22131.html
★IPA、情報流出対策本部を設置
http://www.itmedia.co.jp/enterprise/articles/0901/19/news077.html
★経過を報告するIPA仲田理事
http://image.itmedia.co.jp/enterprise/articles/0901/19/ipa.jpg
★IPA職員が収集、流出した とんでもない「反社会的」情報
http://www.j-cast.com/2009/01/20033932.html
★プレス発表 当機構職員のパソコンによる情報流出等について
http://www.ipa.go.jp/about/press/20090119.html
★情報流出のIPA職員、停職3カ月の処分に
http://japan.cnet.com/news/sec/story/0,2000056024,20386662,00.htm
★IPA職員の懲戒処分を発表 - 私物PCからの大量情報流出問題で
http://journal.mycom.co.jp/news/2009/01/19/018/index.html
★IPA流出騒動の職員、処分の実質は3ヶ月の有給休暇
http://www.tanteifile.com/newswatch/2009/01/20_01/index.html
★IPA流出職員 停職3ヶ月"有給休暇"処分にネット住民激怒!
http://uratan.jp/hotnews/2009/01/7869/
484464:2009/01/24(土) 22:34:58
>>465
探してみたんですが、yamlのC用パーサって少ないですね…

>>466
JSONをCで使うのってどうなんでしょう…?

>>467
よく考えたら、テキストとして読めた方が良いかも。

>>470
ちょっと見てみたんですが、頭が回らない…


そもそも、C言語使っていること自体が間違っているような気がしてきた…
こういうの向きじゃないのね
485デフォルトの名無しさん:2009/01/24(土) 22:49:24
何に食わせて再利用したいかってのが決まってないと何とも言えないと思う
XMLとかにした所で、どのタグが何の意味なのかってのはどっかで別に解釈しなきゃならんわけで
形式だけ汎用方式にしたからってすぐ再利用出来るとは限らないし
486デフォルトの名無しさん:2009/01/24(土) 23:30:51
std::tr1::unordered_map<const char*, int> MAP;
MAP.insert(make_pair("abcd", 1));
char *name = (char*)malloc(5*sizeof(char));
strcpy(name, "abcd"), name[4] = 0;
printf("1,%d\n",MAP.count("abcd"));
printf("2,%d\n",MAP.count(name));

gccで↑の様にした時、二番目に表示されるポインタの所で参照出来ませんでした。
std::map の時は↓の様にすれば参照出来たのですが、unordered_mapで同様な事を出来ませんでしょうか。

namespace std {
template <> struct less<const char*> : binary_function<const char*,const char*,bool> {
bool operator()(const char* x, const char* y) const {
return strcmp(x, y) < 0;
}
};
487デフォルトの名無しさん:2009/01/24(土) 23:40:39
>>486 std::tr1::unordered_map<std::string, int>
488デフォルトの名無しさん:2009/01/24(土) 23:56:59
>>487
const char* でやりたいのです。
489デフォルトの名無しさん:2009/01/25(日) 00:05:46
>>486
よくわかんないけどうちの環境でコンパイルしたら
>g++ temp.cpp -Wall
>ls
a.out temp.cpp
>./a.out
1,1
2,0
>gcc --version
gcc (GCC) 4.1.2 20070626 (Red Hat 4.1.2-14)
Copyright (C) 2006 Free Software Foundation, Inc.
以下略……

って出たよ。
490デフォルトの名無しさん:2009/01/25(日) 00:14:02
hashとpredを自分で定義するだけでいけるだろ
491デフォルトの名無しさん:2009/01/25(日) 00:18:28
>>489
それを↓のようにしたいのです。
1,1
2,1
492デフォルトの名無しさん:2009/01/25(日) 17:34:56
>>486
本題とは関係ないけど
> namespace std {
> template <> struct less<const char*> : binary_function<const char*,const char*,bool> {

これって std::less の特殊化だけど、ユーザー定義型じゃないから未定義動作になるよ。
std の外で別の型名で作って std::map のテンプレート引数に渡すとか、別の方法にしないとダメだよ。
493デフォルトの名無しさん:2009/01/25(日) 19:10:06
>>490>>492
取り合えずこんな感じで指定してみましたが結果は変わらず…。
何かやり方が悪いのでしょうか?

struct MyLess : binary_function<const char*,const char*,bool> {
bool operator()(const char* x, const char* y) const {return strcmp(x, y) == 0;}
};
std::tr1::unordered_map<const char*, int, std::tr1::hash<const char*>, MyLess> MAP;
494デフォルトの名無しさん:2009/01/25(日) 19:14:25
>>493
なんでハッシュがそのままなんだよ。
なんで等値比較関数の名前が MyLess なんだよ。

ハッシュマップの構造が理解できるまではおとなしく std::map のままにしとけよ。
495デフォルトの名無しさん:2009/01/25(日) 19:33:43
>>494
すみません、適当すぎました。こんな感じでしょうか?まだ上手くいかないのではありますが…。

struct MyHash {
 size_t operator()(const char* s) const { return std::tr1::hash<const char*>()(s); }
};
struct MyEqual_To : binary_function<const char*,const char*,bool> {
 bool operator()(const char* x, const char* y) const { return strcmp(x, y) == 0; }
};
std::tr1::unordered_map<const char*, int, MyHash, MyEqual_To> MAP;
496デフォルトの名無しさん:2009/01/25(日) 19:34:55
>>495
> struct MyHash {
>  size_t operator()(const char* s) const { return std::tr1::hash<const char*>()(s); }

これで何が変わると思ってんの?
497デフォルトの名無しさん:2009/01/25(日) 19:57:45
そういう所をお教え願えませんでしょうか・・・?
498デフォルトの名無しさん:2009/01/25(日) 19:57:47
ワロタ。ポインタ渡しても意味ないよ。
size_t operator()(const char* s) const {
size_t h = 0;
while(*s++ != '\0') boost::hash_combine(h, *s);
return h;
}
boost::hash_combine使えないなら h += *s;とかでもとりあえずはいける。衝突が多くなって遅くなりそうだけど。
499デフォルトの名無しさん:2009/01/25(日) 20:00:10
ミスったこうだな for(; *s != '\0'; ++s)
500デフォルトの名無しさん:2009/01/25(日) 20:02:12
これでもいいけどな。
struct MyHash {
 size_t operator()(const char* s) const { return std::tr1::hash<std::string>()(s); }
};
501デフォルトの名無しさん:2009/01/25(日) 20:03:26
>>498
なるほど、ハッシュってそういう使い方をするのですね。
その方法で出来ました。ありがとうございます。
502デフォルトの名無しさん:2009/01/25(日) 20:38:02
>>498
h += *s;は酷過ぎるだろ。せめて、Wikipediaのやつを参考にしようよ。
http://ja.wikipedia.org/wiki/%E3%83%8F%E3%83%83%E3%82%B7%E3%83%A5%E9%96%A2%E6%95%B0
503デフォルトの名無しさん:2009/01/25(日) 21:14:54
>>502
それを書くくらいならhash_combineの実装をコピペしたほうがいいと思ったんだよね。一行だけだし。
まあ実験用ってことで
504デフォルトの名無しさん:2009/01/25(日) 21:31:19
>>500
それって中でstd::stringが作られないの?
505デフォルトの名無しさん:2009/01/25(日) 21:46:38
>>504
もちろん。
const char*からstd::stringへの暗黙の変換を行った上で呼び出している。
506デフォルトの名無しさん:2009/01/26(月) 17:13:57
マイコン開発ツールの「KEIL」って何て読むの?
カイル?ケイル?キール?
507デフォルトの名無しさん:2009/01/26(月) 18:23:46
ケーイーアイエル
508デフォルトの名無しさん:2009/01/26(月) 18:36:13
>>507
サンクス!
509デフォルトの名無しさん:2009/01/26(月) 20:50:21
C++だけでなく、Cも関係あるのですが、
stack overrun を検出するツールなどはありますでしょうか?

現在のテスト環境はlinux(kernel 2.6系), gcc(g++)です。
デバッグは主に、valgrindを使ってますが、coreをバックトレースすると、
スタックが壊れてるような感じになっています。
510デフォルトの名無しさん:2009/01/26(月) 21:05:26
>>509
そういう環境依存なことは該当環境スレへどうぞ。
511デフォルトの名無しさん:2009/01/26(月) 21:41:51
509です。環境依存の方に質問し直しました。
512デフォルトの名無しさん:2009/01/29(木) 11:26:42
アセンブラからC++仮想関数を呼ぶにはどうしたらいいでしょうか?
(関数名とVtableの対応は、どうしたら分かるでしょうか?)条件は単一継承のみです。
環境はVCです。
513デフォルトの名無しさん:2009/01/29(木) 12:19:44
家のパソコンを使い、
C言語で小遣い帳を作ることは可能ですか?
514デフォルトの名無しさん:2009/01/29(木) 12:23:21
>>512
コンパイラの生成したコードを真似るといいよ。
別のコンパイラやバージョンの違うコンパイラと組み合わせたら動かなくなるかもしれないけどね。
515デフォルトの名無しさん:2009/01/29(木) 12:23:56
>>513
可能です。
516デフォルトの名無しさん:2009/01/29(木) 12:35:10
>>513
努力と根性があればできる。
517デフォルトの名無しさん:2009/01/29(木) 12:36:28
>>512
組み込み系のコンパイラなんかはリファレンスに呼び出し規約が書いてある
518デフォルトの名無しさん:2009/01/29(木) 16:10:58
>>513
Microsoft Excelを起動すればおk
519デフォルトの名無しさん:2009/01/29(木) 21:42:19
>>512
素直に普通のCの関数でラップするのが楽。
class Hoge {virtual void Foo();};

extern "C" void call_hoge_foo(hoge* p) {p->Foo();}
520デフォルトの名無しさん:2009/01/29(木) 22:43:42
どうしても最高速でアクセスしたいなら
各環境でいちいち仮想関数内のインデックスを調べるしかないのかね
521デフォルトの名無しさん:2009/01/29(木) 23:48:04
再高速でアクセスしなければいけないものを関数で書くなよ
522デフォルトの名無しさん:2009/01/30(金) 00:16:13
多態ならある程度しゃーない
523デフォルトの名無しさん:2009/01/30(金) 00:16:42
ライブラリなのでは?
524デフォルトの名無しさん:2009/01/30(金) 01:13:44
メンバ関数ポインタとればいいじゃん。
525512:2009/01/30(金) 06:52:59
>>514,517,519-524
簡単なのは、519ですね。高速性を要求されるときは、各環境で仮想関数内のインデックスが必要になるのですが、
そんなときは、524方式で、vtable内で合致するINDEXを調べてアセンブラに教えてあげることにしました。
コンパイラを書いていて、VCで書いたC++クラスを利用したくなったのでお聞きしました。

皆様、どうもありがとうございました。
526デフォルトの名無しさん:2009/01/30(金) 08:14:29
アセンブラから呼ぶときって例外とかどうなるん?
527デフォルトの名無しさん:2009/01/30(金) 18:04:43
C++ワールドの外に出た例外は何を起こすかわからない
528デフォルトの名無しさん:2009/01/30(金) 20:36:14
529デフォルトの名無しさん:2009/01/30(金) 21:57:56
struct T {
 struct poddata pods;
 T() : pods() {}
};
て書いたとき、podsの中身は0クリアしてくれるんだっけ?

要は、コンストラクタの初期化リスト内で : pods() と書いたときの挙動なんだけど
初期化リストに何も書かないときは、pods(内のPODデータ)は何もされないけど
podsを0初期化したい場合は、初期化リストに pods() を加えれば良いのか、ってこと。
もちろん、podsは(手書きの)コンストラクタ等を持っていない場合に。
530デフォルトの名無しさん:2009/01/30(金) 23:08:41
>>524
ちなみに、メンバ関数へのポインタがアドレス(普通のポインタの表現)だと思っていたなら、
それは違うと言っておく。そうでもしないと、メンバへのポインタを介した仮想関数の呼出時に、
多態的にthisに合う関数を選び出す実装が不可能だと思う。
#include <cstdio>
struct Hoge {virtual void Foo() {std::puts("Hoge");}};
struct Piyo : Hoge {virtual void Foo() {std::puts("Piyo");}};
int main()
{
void (Hoge::*pf)() = &Hoge::Foo;
Piyo piyo;
(piyo.*pf)(); //Piyo::Fooが呼ばれる
}
質問者は理解していたようだけど。

531デフォルトの名無しさん:2009/01/31(土) 01:00:46
td::dequeってclearが走るとメモリも開放される(アロケータのdeallocが走る)って規定されてる?それとも未定義?
532デフォルトの名無しさん:2009/01/31(土) 01:06:15
未定義はさすがにないだろwwww
533デフォルトの名無しさん:2009/01/31(土) 01:07:24
実装依存だろう
534デフォルトの名無しさん:2009/01/31(土) 01:15:09
未規定?
535デフォルトの名無しさん:2009/01/31(土) 05:17:08
>>529 それでゼロ初期化になる。
536デフォルトの名無しさん:2009/01/31(土) 05:21:06
>>530
アドレスでも不可能じゃないよ。
「this を受け取って仮想関数テーブルを引いてジャンプする処理」のアドレスで実装できる。
537470:2009/01/31(土) 17:32:30
>470の自己フォロー
ちょうどboost mlに似たような話があって、ここが紹介されていた。
ttp://groups.google.com/group/comp.lang.c++.moderated/tree/browse_frm/thread/4f7c7a96f9afbe44/c95a7b4c645e449f#doc_e5fbc9305539f699

確かに使えるけど、けっこう大袈裟になるんだね。
538デフォルトの名無しさん:2009/01/31(土) 19:41:35
例外をoffにした場合って、newが失敗した場合はNULLが返ってくるんでしょうか?仕様として。
539デフォルトの名無しさん:2009/01/31(土) 19:43:39
>>538
「例外をoff」の時点で標準から外れるので、この場合の仕様はコンパイラしだい。
マニュアル嫁
540デフォルトの名無しさん:2009/01/31(土) 19:54:45
>>539
ありがとうございます。マニュアルみます。
541デフォルトの名無しさん:2009/01/31(土) 20:01:25
仕様として、std:nothrow指定すればnewを失敗したときにNULLを返す。
542デフォルトの名無しさん:2009/01/31(土) 20:32:45
>>541 それ、コンストラクタからの例外に効かないからあんまり意味無いよ。
543デフォルトの名無しさん:2009/02/01(日) 02:10:30
3年ぶりにc++の仕事に戻ってきたんだけど
お勧めのログ出力のライブラリってありますか
log4cppとかboostにも一応あるみたいだけど。
544デフォルトの名無しさん:2009/02/01(日) 04:42:58
教えて!えろい人!
明示的に参照を取ろうと思ったんだけどうまくいかない。
boost::ref参考にして作ってみたんだけど。
何が悪いんですか?

http://codepad.org/CSl3Pc84
545デフォルトの名無しさん:2009/02/01(日) 05:04:01
>>544
それ、boost::refでも全く同じ結果になるよ。問題ない。
546デフォルトの名無しさん:2009/02/01(日) 07:44:49
>544
template はどんな型でも受けるんだから T = refwrap<U> の場合もある。
そして変換関数の呼び出しが必要ない分、F<>(refwrap<T>) が F<>(int&) よりもオーバーロードの解決で優先される。
547デフォルトの名無しさん:2009/02/01(日) 08:25:41
>>544
boost::refってそうやって実装してるのか勉強になったよ
548デフォルトの名無しさん:2009/02/01(日) 09:07:47
>>546
2版目のFは明示的にT&を返すメンバ関数呼んでるんだけど、なんでF<>(int&)に解決されないの?
549デフォルトの名無しさん:2009/02/01(日) 13:25:13
printf()
550デフォルトの名無しさん:2009/02/01(日) 13:30:24
>548
すっとぼけたこと言ってすまんかった。

> 14882:2003 5 Expressions/6
> If an expression initially has the type “reference to T” (8.3.2, 8.5.3), the type is adjusted to “T” prior to any
> further analysis, the expression designates the object or function denoted by the reference, and the expression
> is an lvalue.

により参照はずした後で解析が行われるため型導出(type deduction)の結果は F<int&>(int&) ではなくて F<int>(int) になる。
551デフォルトの名無しさん:2009/02/01(日) 13:32:57
templateの型がどれに決定されたのかをコンパイル時に見たいんだけど(エラーメッセージでいい)
どう書けば確実に見れます?Borlandで
552デフォルトの名無しさん:2009/02/01(日) 13:35:51
普通は見れないし強引に見る方法もほとんどない
あらゆる特殊化にprintf仕込んでおくしかない
553デフォルトの名無しさん:2009/02/01(日) 13:52:12
>>551
typedef typename T::undefined_t UNDEFINED_T;
で発生させたエラーメッセージで見れた。VCだけど。
554デフォルトの名無しさん:2009/02/01(日) 14:21:29
typeid(T).name() を出力すれば?
555デフォルトの名無しさん:2009/02/01(日) 14:21:51
ああ、コンパイル時か・・・
すまんかった
556デフォルトの名無しさん:2009/02/01(日) 16:17:16
>>553おー見れましたよ。サンクス
557デフォルトの名無しさん:2009/02/01(日) 20:27:10
もっかい聞きます。お勧めのログ出力のライブラリってありますか
log4cppとかboostにも一応あるみたいだけど。
環境はg++、linuxです
558デフォルトの名無しさん:2009/02/01(日) 21:03:20
>>557
挙げてる奴でダメな理由を出さないと別のは挙げようがないんじゃね?
559デフォルトの名無しさん:2009/02/01(日) 21:18:30
printf()
560デフォルトの名無しさん:2009/02/01(日) 21:28:57
>>557
C++におけるオープンソースライブラリの隆盛がわからんのです
boostがデファクトというのは理解出したんだけど
ログは日本語のboostサイトには紹介されてなかったので何か他にいいのがあるのかな、と
log4cppはjavaで慣れてるんだけど引数にストリーム使わないっぽいし
かと思えば一般的にストリームもあまり利用されてないとか
よくわからんのです
561デフォルトの名無しさん:2009/02/01(日) 21:33:07
>>560
使ってみて自分の必要とする機能さえついてれば、隆盛とか関係ないだろ?

boost より開発がアクティブなやつを挙げろと言われても無理だろうしな。
562デフォルトの名無しさん:2009/02/02(月) 00:06:03
>>550
thx.

よくわからんかったけど・・・w
563デフォルトの名無しさん:2009/02/02(月) 00:26:54
>562
「T への参照型」となる式は、いかなる解析よりも前に T 型へと調整され、参照先のオブジェクトあるいは関数を指し示す左辺値となる。
つまり関数テンプレートの型導出の前に、int& 型を持つ r.getref() は int 型と見なされてしまい、結果 T が int として導出される。
564デフォルトの名無しさん:2009/02/02(月) 14:08:02
F<int&>(i)
565デフォルトの名無しさん:2009/02/02(月) 16:10:09
(i)←まんこ?
566デフォルトの名無しさん:2009/02/02(月) 21:00:10
struct X{
virtual ~X(){}
virtual void p(){}
virtual void p(int){}
};
struct Y:public X{
void p(){}
};

このように継承先で親クラスのオーバーロード関数の一つをオーバーライドするとX::p(int)がY::p()に隠蔽されると出ます。
これを鎮めることはできますか?BCC5.5のクソパイラです。
567デフォルトの名無しさん:2009/02/02(月) 21:10:45
Y::p(int)もオーバーライドすればいいよ
568デフォルトの名無しさん:2009/02/02(月) 22:45:34
クラスが同じだと異なるオブジェクトでもプライベートメンバーにアクセスできるのだが
C++の言語設計者って馬鹿なの?

class A {
 int n;
 A(int m){n = m;}
 int func(const A& a){ return a.n; }
}

A a1(1), a2(2);
cout << a1.func(a2); << endl;
569デフォルトの名無しさん:2009/02/02(月) 22:46:08
>>567ありがとうございました。
570デフォルトの名無しさん:2009/02/02(月) 22:46:29
>566
>このように継承先で親クラスのオーバーロード関数の一つをオーバーライドするとX::p(int)がY::p()に隠蔽されると出ます。

その挙動自体は規格準拠。

struct Y:public X {
  using X::p;
  void p() {}
};

と書けばいいはずなんだけど、BCC5.5 で通るかは分からない。
571デフォルトの名無しさん:2009/02/02(月) 22:47:10
>>568自クラスのことすら把握できないって馬鹿なの?
572デフォルトの名無しさん:2009/02/02(月) 22:50:45
>>570通りますが、警告は出っ放しでした。
573デフォルトの名無しさん:2009/02/02(月) 23:08:00
>>568
operator ==とかこうでないと実装できないだろって例ならいくらでも挙げられる。
あと、逆にこうなっていない言語って何がある?
574デフォルトの名無しさん:2009/02/02(月) 23:11:29
いくらでも挙げられるつーなら、一つくらい挙げてみろよ
575デフォルトの名無しさん:2009/02/02(月) 23:17:17
コピーコンストラクタ
576デフォルトの名無しさん:2009/02/02(月) 23:20:23
operator ==だろ
あとoperator !=とか
operator <とかoperator <=とか
operator >やoperator =>もそうだな
operator +だってそうだしoperator -にoperator *にoperator /
operator %もそうだ
それからoperator &とかoperator |とか
operator ^も
変わった所ではoperator ->*なんてのもあるな
ちなみにoperator &&もそうだけどやっちゃダメだぞ
operator ||とoperator ,もね

あ、忘れてた。operator =
577デフォルトの名無しさん:2009/02/02(月) 23:23:09
同じクラスのものなのにプライベートメンバにアクセスできない方が異常
578デフォルトの名無しさん:2009/02/02(月) 23:23:11
class A {
 int n;
 char c;
public:
 A(int m, char d):n(m),c(d){}
 A(const A& a):n(a.get_n()),c(a.get_c()){}
 bool operator==(const A& a) const { return n == a.get_n() && c == a.get_c(); }
 A operator+(const A& b) const { return A(n+b.get_n(),b.get_c()); }
 int get_n() const { return n; }
 char get_c() const { return c; }
}

A a1(1,'a'), a2(2,'b');
cout << a1 == a2 << endl;

できないこともない
privateの意味がないけどな!
579デフォルトの名無しさん:2009/02/02(月) 23:30:39
A::operator==(const A& a){private_member = a.private_member;}
ができるのに、じゃあなんで
A::operator==(const B& b){private_member = b.private_member;}
ができないんだよ。

C++の言語設計者は明らかにアホ。
580デフォルトの名無しさん:2009/02/02(月) 23:31:26
別クラスの private メンバ見れたらカプセル化壊れるだろwww
581デフォルトの名無しさん:2009/02/02(月) 23:32:22
別オブジェクトのpriveteメンバが見られても同じことだろ
582デフォルトの名無しさん:2009/02/02(月) 23:37:56
確かに問題だな。
C++0xで修正されるんじゃないの?
583デフォルトの名無しさん:2009/02/02(月) 23:39:33
>>581
比較のために公開したくもないメンバを public メンバ関数で公開しなきゃいけない方が問題だろ
584デフォルトの名無しさん:2009/02/02(月) 23:40:14
自分のクラスの面倒くらい
private で面倒みさせてくれよw
585デフォルトの名無しさん:2009/02/02(月) 23:44:53
自オブジェクトからしかアクセスできないアクセス指定子が必要だな

名前は何がいい?
586デフォルトの名無しさん:2009/02/02(月) 23:46:52
secret
587デフォルトの名無しさん:2009/02/02(月) 23:47:27
private
588デフォルトの名無しさん:2009/02/02(月) 23:49:36
masturbate
589デフォルトの名無しさん:2009/02/02(月) 23:52:39
なんで0*HUGE_VALって落ちるの?
あと、doubleで0除算ってINF返してくれるんじゃないの?何で落ちるの?
590デフォルトの名無しさん:2009/02/02(月) 23:54:38
C系言語は伝統的に浮動小数点の扱いが超適当だから
その辺ちゃんとやりたいならFortran使いなさい
591デフォルトの名無しさん:2009/02/02(月) 23:57:16
それはない
592デフォルトの名無しさん:2009/02/02(月) 23:58:44
>>588
採用
593デフォルトの名無しさん:2009/02/03(火) 00:10:42
C89は「NaN?INF?-0?何それおいしいの」って感じだった
そんなだからC++の方でもほったらかしだった
C99で対応したけどやっつけだったからクッチャクチャになった
C++0xは真面目に対応する気はないらしい

C/C++の浮動小数点に期待するな
594デフォルトの名無しさん:2009/02/03(火) 00:12:03
C#でいいじゃん
595デフォルトの名無しさん:2009/02/03(火) 00:38:46
>>583
そんなときのためのfriendだろ。
596デフォルトの名無しさん:2009/02/03(火) 00:48:40
>自オブジェクトからしかアクセスできないアクセス指定子

静的にきめられねぇだろJK
597デフォルトの名無しさん:2009/02/03(火) 01:02:11
Objective-C<呼んだ?
598デフォルトの名無しさん:2009/02/03(火) 01:03:02
むしろオブジェクトが1個しか作れないようにすればいいんじゃないか?
599デフォルトの名無しさん:2009/02/03(火) 01:31:00
this->つけて使わないとコンパイルエラーになるのはちょっとほしいと思った。
600デフォルトの名無しさん:2009/02/03(火) 01:41:21
>568
パフォーマンスを高めるための妥協案。D&Eになんか書いてあったような気がする。
インスタンスごとにアクセス権を設定しても利点が少ない割にコストがデカくなる。

まあ、インスタンスとクラスの概念をごっちゃにしていると>568みたいに思うこともあるよな。
俺も昔はそうだったし。
601デフォルトの名無しさん:2009/02/03(火) 02:58:04
>>593
Dでいいじゃん。

!<>=(順序づけ可能でない)とか、!<>(順序づけ可能でないか等しい)とか組み込み演算子であるよ!
602デフォルトの名無しさん:2009/02/03(火) 03:04:38
603デフォルトの名無しさん:2009/02/03(火) 07:33:10
>>600
>まあ、インスタンスとクラスの概念をごっちゃにしていると>568みたいに思うこともあるよな。

どうしてそう思ったの?
>>568ではクラスとオブジェクト(インスタンス)を厳密に使い分けているが?
604デフォルトの名無しさん:2009/02/03(火) 08:49:26
>>603
600 じゃないけど、いちおう言葉は使い分けているものの、クラスの整合性を保つ責任が
どこにあるかという点でごっちゃにしていると思う。
605デフォルトの名無しさん:2009/02/03(火) 09:29:34
>>600
まぁ疑問に思うことはあるかもしれないけど、そこですぐ「○○は馬鹿」とはならんよね、普通。
頭の悪い奴ほど、不足だらけのデタラメな知識体系で
「わかってる俺と、わかってない他者」って関係を見出したがるけど。
606デフォルトの名無しさん:2009/02/03(火) 14:01:08
>>605

だからと言って、「頭の悪い奴」にはならないよね。
まさに、「デタラメな知識」ですね。わかります。

>「わかってる俺と、わかってない他者」って関係を見出したがるけど。

お前が「わかってる俺」で、>>600は「わかってない他者」ですね。わかります。
607デフォルトの名無しさん:2009/02/03(火) 14:03:40

人に説明して分かって貰えない時は、説明の仕方が悪いと思え。
608デフォルトの名無しさん:2009/02/03(火) 15:45:04
>>568 はヴビ厨なんだよ、きっと。
609デフォルトの名無しさん:2009/02/03(火) 17:47:18
>>602
アホな理由が分からない。
スレチなので、よければDスレに理由を書き込んでホスィ。
http://pc11.2ch.net/test/read.cgi/tech/1226631916
610デフォルトの名無しさん:2009/02/03(火) 21:48:06
アホ=cool
611602:2009/02/03(火) 22:15:52
>>609
アホにはわからないよ
612600:2009/02/03(火) 22:16:55
>605
おいおいおい、誰も馬鹿なんて言ってないぜ。噛み付くなよ。

理由は>604の通りですな。どうせプログラマはクラス単位でプログラムするから、
わざわざインスタンスでアクセス制御するメリットがあんまりないんだよね。
もしインスタンス単位でアクセス制御したいんだったら、そういう風にクラスを作ればよろし。
613デフォルトの名無しさん:2009/02/03(火) 22:31:22
>>604
それでは、「クラスの整合性を保つ責任」と言う言葉を使って、
>>568がインスタンスとクラスの概念をごっちゃにしている、
ということを君なりに説明してくれないか?
614デフォルトの名無しさん:2009/02/03(火) 22:32:18
>>606
>だからと言って、「頭の悪い奴」にはならないよね。
ん?拙い知識で言語仕様にケチをつける >>568
俺からみても、とても頭の悪い人にしかみえないけど。

>>612
>>605>>568 を揶揄しているようにしか読めないわけだが。
615デフォルトの名無しさん:2009/02/03(火) 22:44:01
行間()読めないやつはかき込むなよ
616デフォルトの名無しさん:2009/02/03(火) 22:59:29
行間を期待するプログラマはバグを埋め込む三流の派遣

コンパイラは行間など読んでくれない
617600:2009/02/03(火) 23:18:07
>614
スマン、素で勘違いした。

>613
・インスタンスとクラスは別物
・プログラマが設計するのはクラス(インスタンスじゃない)
というあたりがちゃんと判っていれば、>568のような全否定の言葉は出て来ないんじゃない?

まあ、言語設計を馬鹿にするんだったら、せめてD&Eとガウディ本ぐらいの知識は持って欲しいなぁ。
馬鹿相手にすると疲れるし。
618デフォルトの名無しさん:2009/02/03(火) 23:32:01
「クラスの整合性を保つ責任」は何処行っちゃったの?
619デフォルトの名無しさん:2009/02/03(火) 23:40:27
>>617
その本のどの部分の知識が反論に当たるのか示せなければ
お前は単なるD&Eとガウディ本の威を借る狐だ。
620600:2009/02/04(水) 00:11:53
ああ、ああ、判った判った。ウザいな。
突っ込み入れるだけじゃなくて少しは有益な情報を追加してくれよ。相手するのも疲れるわ。

D&Eは「2.10 保護の方式」にコメントが載ってますな。
インスタンス単位で制御できるようにすることで何か新しいことができるようになると感じるのは錯覚だと断言してるね。

ガウディ本だと「7.3.3 カプセル化制御」のあたりかね。色々な言語のアクセス制御について整理されている。

しかし、2chとはいえもう少しは有意義な話をしようぜ。
621デフォルトの名無しさん:2009/02/04(水) 00:13:17
>>616
人間に対するときとコンパイラに対するときと、同じようにしか接することが出来ないプログラマは
コミュニケーションが取れない三流の派遣
622デフォルトの名無しさん:2009/02/04(水) 00:18:03
>>620
ようやく有意義な書き込みを書けたね^^
623600:2009/02/04(水) 00:21:54
あと、>619
「プログラマが整合性を保つ責任を持つのはクラス」ということかね。
インスタンスの整合性は、あくまでクラス設計から導き出される間接的なものでしかないよね。
インスタンスの視点では設計の整合性を保てない場合もあるし。例えばSingleton/Multitonとか。

あるいは
 プログラマが設計できるのはクラスで、インスタンスは間接的にしか設計できない。
 なのでクラス視点のアクセス制御があっても何ら不思議ではないし、インスタンス毎の
 アクセス制御ができなくても何ら不思議ではない
 だから>568は短絡的すぎ
とでも言っとくかね。
624デフォルトの名無しさん:2009/02/04(水) 00:31:46
>>623
C++はC#よりつおいでつか?
625デフォルトの名無しさん:2009/02/04(水) 00:40:05
>>623
クラスを「メーラーのソース」、インスタンスを「メーラー」と読み替えると、
僕のメーラーから君のメーラーへのアクセス制御ができなくても何ら不思議じゃないことになるね。

プログラマが設計できるかどうかという観点で区別するのは正しいのかな?
626デフォルトの名無しさん:2009/02/04(水) 00:47:04
読み替えてる時点で違うものになってるから。

会話で勝った気になりたいだけのウザイやつは死ねよ。
627デフォルトの名無しさん:2009/02/04(水) 00:54:48
死ねとか言い出したら負けだろ
628600:2009/02/04(水) 01:06:28
>625
C++の場合、そういうのは「同じユーザーが2つのメーラーを立ち上げている」ようなケースじゃない?
あくまでプログラマがクラスを使用するんだから、同一プロセスで同一クラス同士のインスタンスが
通信してもそんなに問題にはならないと思うけど、どうよ。
「僕のメーラーから君のメーラー」というのはプロセス間通信みたいなモンだと思う。
629デフォルトの名無しさん:2009/02/04(水) 06:25:08
>>627
肝心の言語の話がまるで理解できず、「死ね」の部分にしか反応できないと
そういう考えになるかもな。
630デフォルトの名無しさん:2009/02/04(水) 07:56:08
>>628
「同じユーザーが」と言う仮定はどこからきたの?
マルチユーザー環境なら世の中に山ほどあるよ。Windowsしか使ってないと分からないかもしれないけど。
631デフォルトの名無しさん:2009/02/04(水) 12:24:59
>>622
お前もちったあ見習えよ。

>>626
内容が理解できないときは例え話です。
誤謬なんか気にしちゃ駄目なんです。

>>624
打たれ弱いけど速いよ!
632デフォルトの名無しさん:2009/02/04(水) 17:56:10
ここで聞いていいのか分からないけれど、他に適切なスレがあれば教えて下さい。
DLL内の関数でメモリを確保して、それを呼んだ側でスマートポインタに入れる、
というのはメモリの管理上問題ないですか?

dll_func(vector<T*>& v) { v.push_back(new T()); }

main_func(void) {
vector<T*> v;
dll_func(v);
vector<shared_ptr<T> > u(v.size());
for (size_t i=0; i<v.size(); ++i) { u[i].reset(v[i]); }
}

633デフォルトの名無しさん:2009/02/04(水) 18:10:14
問題ないけど危ない設計
634デフォルトの名無しさん:2009/02/04(水) 18:10:47
ちゃんとデアロケータ呼ばれるか心配だな
635632:2009/02/04(水) 18:16:02
>>633-634
どうもありがとう。「危ない」というのは人間側の問題でしょうか?
例えばDLL側にファクトリ関数のようなものを実装する場合は他に何か一般的な方法がありますか?
636デフォルトの名無しさん:2009/02/04(水) 18:18:55
>>632
バージョン含め同じコンパイラで同じランタイムライブラリに動的リンクするようにすれば上手くいく可能性が高い。

そうでないなら、dll_func側のnew/deleteとmain_func側のnew/deleteが別物になるので大いに問題あり。
Tについてはdll_funcの引数をvector<shared_ptr<T> >にすればいい。
そして、vector<shared_ptr<T> >を両者共通で使えるメモリ確保ルーチンを使ったアロケータを使うようにする。

ただ、前者でもdll_funcの引数でvector<shared_ptr<T> >にしたほうがいい。しない理由がない。
637632:2009/02/04(水) 18:22:54
>>636
ふむぅ、なるほど。確かにしない理由がないですね。
とりあえず問題点はわかりました。
ありがとうございました。
638600:2009/02/04(水) 21:26:45
>630
最初のメタファが狂ってんだよ。
腐ったメタファなんか使わずに、どういうことで問題になるのか具体的にきっちり言えよ。
もともとの例え話がダメダメなんだから、『「同じユーザーが」と言う仮定はどこからきたの? 』
なんて突っ込まれてもこっちが困るんだがねぇ。
C++のプログラムだと「僕」が誰で「君」が誰で「僕のメーラー」と「君のメーラー」を実行するということが
どういうことか、きっちり説明してもらおうかね。
“僕のメーラーから君のメーラーにアクセスされると困る”というのなら、素直にメーラー捨てろよ。
同じように、プログラムするときに困るならクラスも捨てろ。
そんなもんメーラー/クラスの設計次第だろ。(あるいはOSとかの下位層の仕事)

『クラスの設計者がバックドアを仕込んで別プロセスにデータを流すかも知れないから
言語でprivateアクセスはインスタンス単位で制御しないと危険だ』
とでも言いたいのかね?だとしたらムダも良いところだな。
同一クラスのインスタンスで情報をやり取りする方法はいくらでもあるし、インスタンス単位で
アクセス制御するコストは馬鹿みたいにデカくなりそうだしな。
639デフォルトの名無しさん:2009/02/04(水) 21:48:57
いつまでも煽り合ってるなよ。
>>600にあるとおりパフォーマンスが理由でFAでしょ。

はい、次の相談者どうぞ。
640デフォルトの名無しさん:2009/02/04(水) 21:57:14
> パフォーマンスが理由でFAでしょ。

アホ
641デフォルトの名無しさん:2009/02/04(水) 22:38:32
「D&E読め」で終わる話をいつまで続けるつもり?
642デフォルトの名無しさん:2009/02/04(水) 22:45:14
相手を黙らせるまでだろ?
643デフォルトの名無しさん:2009/02/04(水) 22:46:20
君が!n(ry
644デフォルトの名無しさん:2009/02/04(水) 23:19:08
ヒープからメモリ取るのにmalloc使って引数にsizeofどうたらと書くのが面倒だったので
こんなの作ったんですが問題はないでしょうか
一応エラーとかはなく動いてるみたいです

template <int Size>
class Buffer{
 char buf[Size];
public:
 Buffer(){this->~Buffer();};
};

int main()
{
 void *p = new Buffer<100>;

 //pをただのメモリの塊として利用

 delete p;
}
645デフォルトの名無しさん:2009/02/04(水) 23:23:40
例外安全性がないし、void * にキャストした後に delete した動作は未定義なので失格
素直に std::vector 使え
646デフォルトの名無しさん:2009/02/04(水) 23:23:53
>>644
厳密に言うと、それを解放するには、operator delete(p)としないといけないと思う。
ところで、それだとmallocやnew char[]を使わない利点が見えてこないけど。
647デフォルトの名無しさん:2009/02/04(水) 23:25:57
operator delete するなら new 側も operator new を直接使わないと
648デフォルトの名無しさん:2009/02/04(水) 23:29:28
class Buffer {
public:
 Buffer(size_t size) : m_buf(size) { }

 void *data() { return &m_buf[0]; }
 const void *data() const { return &m_buf[0]; }

 operator void *() { return data(); }
 operator const void *() const { return data(); }

private:
 std::vector<char> m_buf;
};

てか、バイト単位で指定させるだけなら、結局 sizeof 必要なんじゃね?
649デフォルトの名無しさん:2009/02/04(水) 23:38:05
>>647
作る側はnew演算子(operator new関数→コンストラクタ)の後、
デストラクタを呼んでいるから、operator delete関数呼出で釣り合う。
650デフォルトの名無しさん:2009/02/04(水) 23:45:17
>>645
void*のdeleteは未定義なの?
operator deleteの定義をみると
特に問題なさそうだが
651デフォルトの名無しさん:2009/02/05(木) 00:10:08
this->~Buffer()
ってことは、このメモリ領域、その後なんかでnewした時に割り当てられるってことないの?
652デフォルトの名無しさん:2009/02/05(木) 00:12:38
すいません、あと、delete p;
って既に開放済みなのにdeleteできるの?
653デフォルトの名無しさん:2009/02/05(木) 00:14:06
C++ってscanf()に相当することをしようと思ったらscanf()使うしかないわけ?
654デフォルトの名無しさん:2009/02/05(木) 00:16:22
>>651-652
デストラクタ実行とヒープの開放は別なんだろ
655デフォルトの名無しさん:2009/02/05(木) 00:19:24
>>653
scanf相当って「型を指定して得る」って事をいってるのか何のことなのか意味が分からん
std::cinでは足りないと?
656651:2009/02/05(木) 00:26:56
>>654
すみません、色々間違えてました
this->~Buffer() でデストラクトしてるのに
deleteで再度デストラクトしていいの?
2重デストラクトって問題ないの?
657デフォルトの名無しさん:2009/02/05(木) 00:28:30
>>655
std::cinって書式付き入力変換できるの?
できないなら、全然足りない。
658デフォルトの名無しさん:2009/02/05(木) 00:51:46
>>657
std::strstream
659デフォルトの名無しさん:2009/02/05(木) 00:58:24
>>658
scanf()って知ってますか?
660デフォルトの名無しさん:2009/02/05(木) 01:06:54
だったらstdinの中にはいってるからfgetして必要なデータ型に直せば?
661デフォルトの名無しさん:2009/02/05(木) 01:11:11
つまり、iostreamは使えないライブラリだってことね。
662デフォルトの名無しさん:2009/02/05(木) 01:11:59
またそのパターンかよw
663デフォルトの名無しさん:2009/02/05(木) 01:36:51
>>661
(お前にとって)使えないライブラリだ、ってことなら正しい。
664デフォルトの名無しさん:2009/02/05(木) 01:46:37
scanfは危なすぎてC++でまでわざわざ使う気にはなれんなぁ
入力には少々面倒でもcin使うわ

ostreamは本物の糞だから絶対使わないけど
665デフォルトの名無しさん:2009/02/05(木) 01:53:02
どう糞なのか教えていただけないでしょうか
666デフォルトの名無しさん:2009/02/05(木) 01:59:06
今宵も大暴れの予感 age
667デフォルトの名無しさん:2009/02/05(木) 02:04:39
>>665

printf("%08.3f %+04.1f\n", x, y);

std::cout << std::setw(8) << std::setprecision(8) << std::setfill('0') << (int)(x*1000)/1000.0 << " "
<< std::setw(4) << std::setprecision(4) << std::setfill('0') << std::setpos << (int)(y*10)/10.0 << std::endl;
668デフォルトの名無しさん:2009/02/05(木) 02:20:46
Cスタイルキャスト(笑)
669デフォルトの名無しさん:2009/02/05(木) 02:24:42
>>667
setprecisionの引数はそれぞれ3と1では?
670デフォルトの名無しさん:2009/02/05(木) 02:26:29
setprecisionの意味調べ直せカス
671デフォルトの名無しさん:2009/02/05(木) 02:38:50
std::setpos? std::showpos のことか?
672デフォルトの名無しさん:2009/02/05(木) 02:41:00
boost::formatの支援がない環境ではoperator <<(ostream &, T)なんて使わんな
673デフォルトの名無しさん:2009/02/05(木) 02:47:35
>>650
operator delete () 関数の呼び出しは問題ないが
delete 演算子の適用は未定義動作。
674デフォルトの名無しさん:2009/02/05(木) 02:59:16
%fなんだからfixedがいるはず。
675mx4k:2009/02/05(木) 04:02:33
g++で、あるヘッダーファイルを定義するとき、
クラス定義とか関数のプロトタイプ宣言とかを
インクルードガードする分には問題ないのですが、
クラスのメンバ関数の実装とかを書くと
インクルードガードしているはずなのに
multiple definition
って言われてしまう気がするのですが。
しかも必ず再現するわけではないようで…
…これは俺が悪いのですかね?
676デフォルトの名無しさん:2009/02/05(木) 04:11:06
2カ所以上に定義書いてないだろうな…
677mx4k:2009/02/05(木) 04:15:38
これをいろいろなファイル(他のヘッダーファイルA.hやB.h)からインクルードしてみています。
↓↓↓
#ifndef PREVENTION_OF_OVERLAPPING_INCLUSION
#define PREVENTION_OF_OVERLAPPING_INCLUSION 1

class test_for_overlapping_inclusion
{
int m_hoge;
public:
test_for_overlapping_inclusion();
int foo(int num);//このメンバ関数を有効にします。
};
test_for_overlapping_inclusion::test_for_overlapping_inclusion()
{m_hoge=97;}

int test_for_overlapping_inclusion::foo(int num)
{return num+m_hoge;}
#endif


678デフォルトの名無しさん:2009/02/05(木) 04:45:46
>>677
定義をヘッダファイルに書いちゃダメ
それだと多分毎回フルコンパイルしないといけなくなる
679デフォルトの名無しさん:2009/02/05(木) 04:45:55
ポインタってNULL状態でもメモリを消費しますか?
例えば
int *pn = 0;
って書いて
if(pn)
っていう風に処理できるのだからひょっとして4byteぐらいは固定で
消費してしまうなんて事はないですか?
680デフォルトの名無しさん:2009/02/05(木) 04:48:14
>>679
ポインタ変数も普通の変数とその辺りは大差ない。
メモリを消費するかもしれないし、レジスタしか消費しないかもしれない。
もっと極端に、最適化で消えてなくなるかもしれない。
681デフォルトの名無しさん:2009/02/05(木) 04:48:35
>>679
そのとおり。つーかC言語レベルで重症だから変数について学びなおしてこい。
682mx4k:2009/02/05(木) 04:53:56
>>676
>>678
メンバ関数に対してinline指定したらなんか通るようになった。
Why??????
683デフォルトの名無しさん:2009/02/05(木) 04:55:01
>>680
>>681
なるほど・・・早い回答ありがとうごじました。
684デフォルトの名無しさん:2009/02/05(木) 04:57:32
>>682
インライン化されたからだよ
リンカがシンボルを参照する必要がなくなったから
685mx4k:2009/02/05(木) 05:00:10
>>684
なるほど。ありがとうございます。
まあまさかGCCのせいなわけは無いでしょうから俺のせいなんですよね?
皆さんはこんなこと無いですよね?
686デフォルトの名無しさん:2009/02/05(木) 05:42:31
687デフォルトの名無しさん:2009/02/05(木) 10:14:32
>>685
a.cppとb.cppからそのヘッダを参照していたとすると、
それぞれ独立にビルドしてa.oとb.oの両方にfooの実体が含まれることになる。
すると、a.oとb.oをリンクするときに同じ名前の関数が複数あるからおかしなことになる。
688mx4k:2009/02/05(木) 16:29:08
>>686
>>687
読ませていただきました。
「それぞれ独立にビルドして」
という状態がポイント、ということでしょうか?
そのためにインクルードガードしたつもりでもなっていないということでしょうか?

689デフォルトの名無しさん:2009/02/05(木) 16:35:11
グローバル変数を宣言するとき
static つけたときとつけなかったときの違いは分かるか?
690デフォルトの名無しさん:2009/02/05(木) 16:42:13
boostのthreadの昨日を使いたいのですがbjamでビルドしてもエラー麦価で手津空けませ印
解決策plz
691デフォルトの名無しさん:2009/02/05(木) 16:44:55
コンパイル環境とエラー内容を詳しく聞かせてもらおうか。
それとエラーと思っていたけど実は警告でしたーだったら(^ω^ #)ビキビキ
692デフォルトの名無しさん:2009/02/05(木) 16:58:26
windows、VC6.0、boost_1_37_0、boost-jam-3.1.17-1-ntx86つ買ってます
Let's Boostというサイトのディレクトり公正、びるどテジュんをま違いなく倣っているのですが
ここいコピペしきれないほどのエラーはいてあます

...found 4880 targets...
...updating 988 targets...
compile-c-c++ bin.v2\libs\math\build\msvc-6.0\release\link-static\threading-mult
i\acosh.obj
acosh.cpp
.\boost/math/tr1.hpp(179) : error C2632: 'long' と 'long' の 2 つの型指定子のあ
いだにコードがありません。
.\boost/math/tr1.hpp(180) : error C2632: 'long' と 'long' の 2 つの型指定子のあ
いだにコードがありません。
.\boost/math/tr1.hpp(181) : error C2632: 'long' と 'long' の 2 つの型指定子のあ
いだにコードがありません。
.\boost/mpl/aux_/integral_wrapper.hpp(88) : fatal error C1506: ブロックが大きすぎて
、コンパイルできません。

こんあ漢字にえねんと・・・
693mx4k:2009/02/05(木) 17:03:41
>>689
>>グローバル変数を宣言するときstatic つけたときとつけなかったときの違い

static変数は開始時に0で初期化されることが保証されている
…という話ではないですよね。
そういえばstaticつけるとそのファイル内でしかスコープが有効でないんでしたっけ??
694デフォルトの名無しさん:2009/02/05(木) 17:07:29
>>692
VC6がいけないな。
ここのCompilers Testedを見れば分かるように、1.37はもはやVC6を対象にしていない。
http://www.boost.org/users/news/version_1_37_0
695デフォルトの名無しさん:2009/02/05(木) 17:07:35
>>692
1.37がVC6.0に対応しているかどうか調べた?
696デフォルトの名無しさん:2009/02/05(木) 17:17:37
なるほお
VCのヴァージョンをあげるか簿尾sとのヴぁー所のwさげるかです根
とりあえず古いBoostでたえmしてみることにします
どうもありがとうございましいた
697デフォルトの名無しさん:2009/02/05(木) 17:45:47
std::string str;

std::basic_string<char> str;
は等価だよな?typedefなんだし。
それなのに
std::string::iterator it;
がおkで
std::basic_string<char>::iterator it;
はコンパイルエラーになるのは、なんで?

698デフォルトの名無しさん:2009/02/05(木) 17:49:34
>>697
std::basic_string<char> str;
が通るのは確認したのか?

お前の処理系が古すぎて、basic_string自体無いとか?

699デフォルトの名無しさん:2009/02/05(木) 18:19:57
>>698
遅レスすまそ
とおらねかった。
組み込みうぜー

そして確認不足でスマソ
いつもの感覚でやってたorz
700デフォルトの名無しさん:2009/02/05(木) 18:36:15
>>699
std::basic_string<char, std::char_traits<char>, std::allocator<char> > str;

ここまで書けばコンパイル通る


701デフォルトの名無しさん:2009/02/05(木) 19:59:17
>>696
さすがに、そろそろ新しいの買った方がいいんじゃないか?w
VS2008ならStdで6.0のPro相当だから安いよ。
MSのイベントでタダで配ってたりするらしい。
702デフォルトの名無しさん:2009/02/05(木) 21:43:16
開発環境がVC6ってカキコよく見かけるが
新しいのに移行しないで6を使い続けるってなんか理由あるのか?
古いの保守のため?
703デフォルトの名無しさん:2009/02/05(木) 21:53:17
ISO C++(VS2003以降含む)とVC++6は全く別の言語だから
704デフォルトの名無しさん:2009/02/05(木) 21:54:25
Visual C++ 2005 でOCCI環境10.2gでDBと接続してやっているんですが、
DBから内容を取り出すときにヒープが壊れていますとエラーが出ます。
C++プロパティ(文字:Unicode)

std::string name = "";
name = rs->getString(1); ←getStringの時点でヒープが壊れてしまい(全角文字8文字以上の場合)
エラーを吐き出してしまいます。
C++環境でgetString以外、またはgetStringをこう改良したら、壊れないっていうのってないでしょうか?

google先生に助けを求めて二週間以上立っても俺には見つけれませんでした…
最終的な形は、取り出した値をString^ に変換するかんじです・・・
よろしくお願いします
705704:2009/02/05(木) 21:57:28
失礼しました、DBはVARCHAR2で作っています
706デフォルトの名無しさん:2009/02/05(木) 21:58:42
rsがどこからでてきたんですか><;;;
707デフォルトの名無しさん:2009/02/05(木) 22:00:28
オープンソース開発とかだと、VC6のプロジェクトファイルであれば
それ以降のバージョンすべてで使えるという利点があるが、
普通の人には関係ないな。
708デフォルトの名無しさん:2009/02/05(木) 22:02:36
結局VCでしか使えないうえに、
言われてるように仕様が変わりすぎて、vc6とvs200x使ってる人たちが協力するとかありえないだろw
709デフォルトの名無しさん:2009/02/05(木) 22:10:48
VCって何であんなにクソなの?
710704:2009/02/05(木) 22:12:28
>>706
失礼しました、流れはこんな感じです(部分抜粋)

private:
Statement *stmt;
ResultSet *rs;
をしておき、オラクルにログイン

this->stmt = conn->createStatement();
rs = stmt->executeQuery("SELECT文");

std::string name = "";
String^ Name = "";

while(rs->next()){
name = rs->getString(1);
}
Name = gcnew String(name.c_str());

nameに入る時点ではなく、getStringの時点でエラーが出てるみたいです(ブレークポイントの位置的に)
711デフォルトの名無しさん:2009/02/05(木) 22:13:27
一応MSの擁護もしておくと、VC6の頃はC++の標準規格自体がなくて
ベンダが好き勝手にオレオレ実装するのが当たり前だった頃だから仕方なかった
712デフォルトの名無しさん:2009/02/05(木) 22:58:52
あー。
そうだったんか。
俺はまたてっきりIEの時に標準規格を無視してJavaScriptやHTMLタグの独自実装をした時と同じような現象かと思った。
713デフォルトの名無しさん:2009/02/06(金) 00:08:36
size_t
って
std::size_t
が正しいんだよね?
これって何のtypedefなの?unsigned long?
714デフォルトの名無しさん:2009/02/06(金) 00:16:19
>>713
<cstdlib>をインクルードしたならstd::size_t。

元の具体的な型は決めようがないからこそtypedef。
まあ、std::size_tは符号無し整数型だという決まりはあるけど。
715デフォルトの名無しさん:2009/02/06(金) 00:19:39
>>714
サンクス
あと、wchar_tはstd名前空間じゃないよね?
これは
intとかdoubleとかと同じ組み込み型そのものだから」
という理解で良い?
716デフォルトの名無しさん:2009/02/06(金) 00:19:49
class A{
int m_a;
public:
int* operator&(){return &m_a;}
};
このようなクラスのオブジェクトのアドレスを取得するにはどうしたらよいの?
具体的には CComBSTR 型変数のアドレスが取得したい。
717デフォルトの名無しさん:2009/02/06(金) 00:26:57
>>716
なんかあったねそういう状況。
確かキャストとかを変に重ねて解決するんじゃなかったっけ?
Boostにそういう状況でもアドレスを取得するためのライブラリがあった。

718デフォルトの名無しさん:2009/02/06(金) 00:27:20
>>716
boost::addressofの実装はこんなんなってた
reinterpret_cast<T*>(&const_cast<char&>(reinterpret_cast<const volatile char &>(obj)));
719デフォルトの名無しさん:2009/02/06(金) 00:28:43
>>715
OK、そういうこと。

>>716>>718
事情が無ければboost::addressofをそのまま使えばいいじゃない。
720デフォルトの名無しさん:2009/02/06(金) 00:31:34
size_tはグローバル名前空間にも無いとだめじゃなかったか?
721715です:2009/02/06(金) 00:32:53
>>719
ありがとうございます。
722デフォルトの名無しさん:2009/02/06(金) 00:33:01
戻り値が参照の関数でエラーが起きたらどうやって呼び出し元に伝えるの?

例外しかないって、マヌケじゃない?
723デフォルトの名無しさん:2009/02/06(金) 00:33:42
>>717-719
なるほど。身近に立派な手本があったんだね。
ちょっと勉強してきます
724デフォルトの名無しさん:2009/02/06(金) 00:35:28
意味がわからん。
ポインタだったらnullがあるのにってこと?
725デフォルトの名無しさん:2009/02/06(金) 00:39:24
>>722
どういうこと?
君はどういう実装だったらうれしいの?
例外と参照の意味を考えればそんな変な仕様じゃないと思うがね。
726デフォルトの名無しさん:2009/02/06(金) 00:40:05
例外使う奴って素人だろ
727デフォルトの名無しさん:2009/02/06(金) 00:42:22
あんまり参照のリターン値ってつかわんよね。
return *this; くらい?
728デフォルトの名無しさん:2009/02/06(金) 00:42:41
素人は例外を使えないと思うんだが。
玄人は例外安全を徹底するだろうが。
…じゃあ例外は誰が使うんだ!?!?
729デフォルトの名無しさん:2009/02/06(金) 00:44:13
>>728
クロウトはせっかく例外安全を徹底してるのに、例外をつかわんの?
730デフォルトの名無しさん:2009/02/06(金) 00:44:36
>>727
ostream&と自作クラスを受け取るように
operator <<をオーバーロードし、
ostream&を返す
っていう例があるじゃん。
使うかどうかは怪しいが。
return os;
731デフォルトの名無しさん:2009/02/06(金) 00:45:29
>>729
使うだろうが、使いたくはないんじゃね?
俺は決して玄人じゃないから分からんがね。
732デフォルトの名無しさん:2009/02/06(金) 00:46:20
みんななんだかんだ言っても、
結局C++の事が大好きなんだろ!?
正直に言えよ。好きだって。
このツンデレめ。
733デフォルトの名無しさん:2009/02/06(金) 00:48:20
>>722
俺はNULLオブジェクトを作って、エラーがあったら戻り値でそれを返してる。
734デフォルトの名無しさん:2009/02/06(金) 01:01:52
クラステンプレートとテンプレートクラス
ってどちらが正しい用語?
735デフォルトの名無しさん:2009/02/06(金) 01:09:17
>>734
class template
function template
じゃね?
…絶対かと問われると不安になってきた
736デフォルトの名無しさん:2009/02/06(金) 01:11:50
>>688
インクルードガードの考え方が大幅に間違ってるがもう解決したんだろうか。

実際にコードがどうなるか自分で展開してみるといいんだが。
737デフォルトの名無しさん:2009/02/06(金) 01:12:56
クラステンプレートはクラスのテンプレート
テンプレートクラスはテンプレートから作ったクラス

要するにtemplate<typename T> class Hoge{/*...*/}; がクラステンプレート
Hoge<int>がそのテンプレートクラス
std::vectorはクラステンプレート
std::string(==basic_string<うんたらかんたら>)はテンプレートクラス
738デフォルトの名無しさん:2009/02/06(金) 01:17:43
>>737
一気に明快になった
なるほど
739mx4k:2009/02/06(金) 01:21:54
ひとまず解決したのですが。。。
>>736
インクルードガード…複数インクルードしたヘッダファイルをたどったときに同じヘッダファイルが重複するのを防ぐためのもの
ってことでしょうか?
a.cppでインクルードしてビルドすることとb.cppでインクルードしてビルドすることは全く別にコンパイラは並行作業するってことですか?
740デフォルトの名無しさん:2009/02/06(金) 01:41:20
>>739
インクルードはプリプロセッサ指令に従ってファイル結合してるだけなんだよ。
だからヘッダは宣言のみで実体を書いてはならない。

ヘッダにCという実体を定義してしまったら、
a.cppとb.cppのオブジェクト内にそれぞれCという実体が入ってしまう。
そうするとリンクするときにCはa.cppとb.cppのどちらを使えばいいのかリンカが分からなくなる。

インクルードガードはそれでいい。

コンパイラはコンパイルごとに終了してるのでソースファイルごとに独立して作業。
(Makeツールが何度もコンパイラを起動している)

ビルドとコンパイルは意味違うからな。
741mx4k:2009/02/06(金) 01:51:33
>>740
>>コンパイラはコンパイルごとに終了してるので
>>Makeツールが何度もコンパイラを起動している
なるほどそうだったんですね。
合点がいきました。
その辺ブラックボックスでした。勉強しなきゃ。
742デフォルトの名無しさん:2009/02/06(金) 02:00:38
#undef
ってあんま使えなくね?

bccにて
#define HOGE 1
std::cout << HOGE <<std::endl;
ってやったら1が出力され、そのうしろに
#define HOGE 2
std::cout << HOGE <<std::endl;
ってやったらマクロの多重定義の警告が出たが2が出力された。

ここまではいいんだがその後に
#undef HOGE
std::cout << HOGE <<std::endl;
ってやったら未定義って言われた。
俺は前に定義されているマクロと自分のマクロの重複の影響を除くためにあるのかと思ったらそういう動作はしてくれないみたいだ。
…じゃあ何のために#undefがあるんだろう?

743デフォルトの名無しさん:2009/02/06(金) 02:03:34
#define HOGE 1
std::cout << HOGE <<std::endl;

#undef HOGE
#define HOGE 2
std::cout << HOGE <<std::endl;
744デフォルトの名無しさん:2009/02/06(金) 02:22:09
>>743
それが正しいんだろうけど、俺的には
誰かの作ったヘッダのインクルードとかで
知らず知らずに定義されていたHOGEを
俺が新たに#define HOGE 2ってしちゃった場合、
#undef HOGE
をしとけばHOGEの定義がヘッダの物に戻るのかと思ってた。
まあそんなの役立つ機会無いだろうけど。
つーかマクロが重複したらなぜコンパイルエラーにしないのだろう?
745デフォルトの名無しさん:2009/02/06(金) 02:40:45
いいID出たので記念パピコ
746デフォルトの名無しさん:2009/02/06(金) 03:44:40
コンパイラによっては前処理シンボルの push, pop が出来るぽ(VCとか)。
でも前処理の話はCスレとかの方が妥当かもね。
747632:2009/02/06(金) 03:46:08
クロスDLL問題(?)で再度質問させて下さい。以下でうまくいきません。

void dll_func(vector<shared_ptr<X>, DllAllocator<shared_ptr<X> > >& v) {
 v.push_back(shared_ptr<X>(X::create()));
}

void main_func(void) {
 vector<shared_ptr<X>, DllAllocator<shared_ptr<X> > >& u;
 dll_func(u);
}

template <typename T> struct DLLAllocator : std::allocator<T> {
 ...
 pointer allocate(size_type sz, const void*) { return HeapAlloc(GetProcessHeap(), 0, sz*sizeof(T)); }
 void deallocate(pointer p, size_type) { HeapFree(GetProcessHeap(), 0, p); }
};

struct X {
 ...
 static void* operator new(size_t sz) { return HeapAlloc(GetProcessHeap(), 0, sz); }
 static void operator delete(void* p) { HeapFree(GetProcessHeap(), 0, p); }
};

クラスXのnewとdelete、それからDLLに渡すvectorのアロケータをHeapAllocとHeapFreeに変更したのですが駄目で、
もうどこをどうすればいいのか…。

748632:2009/02/06(金) 03:47:25
書きこんでみてから気付いたけど<X>って<><>に見間違う…
749デフォルトの名無しさん:2009/02/06(金) 04:13:58
>>747
もし、双方のvectorの実装が別物だったら、うまくいかないけど、それは大丈夫?
あと、Xにはnew/delete関数の定義は不要。shared_ptrがうまいことやってくれる。
750632:2009/02/06(金) 04:28:53
>>749
main+dllともにVCの同じソリューション内で同じ構成でビルドしてます。
したがって(というのも変ですが)vectorの実装は両方とも同じです。
両者ともstd::vectorです。

> あと、Xにはnew/delete関数の定義は不要。shared_ptrがうまいことやってくれる。
ΩΩΩ<な、なんだってー

751デフォルトの名無しさん:2009/02/06(金) 04:45:09
みなさん、プログラム関係の仕事に就いてる方も多いのでしょうが、
数学や物理の知識も豊富なのでしょうか?

自分ははっきり言って高校生レベルにも満たないレベルだと思います。
もし必要なら今からでも高校生向けのテキストを買って勉強しようと思うのですが、、
752デフォルトの名無しさん:2009/02/06(金) 05:26:42
ほとんどの場合、いらない。
753デフォルトの名無しさん:2009/02/06(金) 05:29:29
何言ってんだお前
誰でも簡単に開発が出来るように作られたソフト、言語は、誰でも出来て当たり前なんだよ
数学なんか出来て当たり前だろ。
資料もほとんど日本語版はスルーだから英語中国語も必須だし、ググって解決できるのは最初だけだ
各専門分野が必要だと、自分を磨いて初めて社会の一員になれるんだと信じてがんばっても
結局、開発期限に間に合わなくて損害賠償で首吊るんだよ。社長がだけど
今の時代一番IT人口が多いというか出来て当たり前の時代すらとっくに過ぎてて、人件費の安い国からのITドカタに勝てる自身あんのか?
知ってるとは思うが、あいつら九九も桁違いだぞ。
技術ごっこが趣味で、ゲームソフト買う代わりに開発ソフト買うとかいうレベルなら何もいらない
754デフォルトの名無しさん:2009/02/06(金) 05:41:32
スレ違い過ぎてフイタ
755デフォルトの名無しさん:2009/02/06(金) 05:44:16
俺は中学校から始めたけど、幼稚園からやってるやつには勝てる気がしない
あいつらの基本思考回路は母国語じゃなくて機械語だ
756デフォルトの名無しさん:2009/02/06(金) 06:54:12
>>722-733
例外を使うか使わないかがスタイルで選べるように思ってるのがもうおかしい。

例外使わないというなら new もできないし標準コンテナも使えないし、
コンストラクタの失敗を扱うのが相当めんどくさい。

「俺は例外使わない」って言ってる奴でも new や標準コンテナは平気で、
コンストラクタの中でも余裕で使ってたりする不思議。っていうかただの無知だろ。
757デフォルトの名無しさん:2009/02/06(金) 07:24:58
>>714
違う。
<stdlib.h> をインクルードしたら size_t のみ。
<cstdlib> をインクルードしたら size_t と std::size_t の両方。
758デフォルトの名無しさん:2009/02/06(金) 07:26:35
>>756
new(std::nothrow) を知らないのは無知
そして例外を完全に使わないスタイルの人は
STL は使わず独自のものを作るだろう。
759デフォルトの名無しさん:2009/02/06(金) 08:38:40
>>722
参照は初期化されているのが前提だから、エラーは例外で返すのが当然。間違ってもnullを返すのは止めて欲しい。迷惑だから。
エラーを返す関数で参照を返すのがそもそも誤り。どうしてもエラーを返したい場合は、boost:::optionalを使えばいい。
760デフォルトの名無しさん:2009/02/06(金) 12:37:31
>>757
何を根拠に言ってるの?

http://www.23ch.info/test/read.cgi/tech/1186410368/489-505
> http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#456
> によると、
>> Including the header <cxxx> declares a C name in namespace std.
>> Including the header <xxx.h> declares a C name in namespace std (effectively by including
>> <cxxx>), then imports it into the global namespace with an individual using declaration.
> ということで、xxx.h だと std とグローバル両方で宣言されるというのが規格の意図らしい。

次の規格改定で、 #456 で提案されていたとおりの修正が入ることになっているようだ。
つまり
<stdlib.h> をインクルードしたら size_t で使えることが保証される。
<cstdlib> をインクルードしたら std::size_t で使えることが保証される。
それぞれ、保証されないほうでも実装によっては使えるかもしれない。
761632:2009/02/06(金) 13:51:26
>>747-750 の続きです

1. スレッドAがスレッドB(main_func)を起動、このときAからBへvector<shared_ptr<T>, DllAlloc<T> > vをポインタ渡し
2. スレッドBはvをDLLに渡す:main_func内でdll_func(vector<shared_ptr<T>, DllAlloc<T> >& v)を呼ぶ
3. dll_func内でvに要素追加:v.push_back(shared_ptr<T>(T::create()))
4. dll_funcから処理が返った後、main_func内でvは問題なく使える
5. スレッドB終了時、例外で落ちる。

main_funcでvの要素を作成した場合には、dll_func内でその要素の値を読み書きしても落ちませんでした。
些細なことでも結構ですので、心当たりか手がかりがあればお願いします。
762632:2009/02/06(金) 13:52:23

DllAlloc<T>はDllAlloc<shared_ptr<T> >の誤植です。
763デフォルトの名無しさん:2009/02/06(金) 13:56:08
>>761
固定手順で問題が再現できるなら、あとはさっさとデバッガつないでトレースなりなんなりしろよ。

スレ違いだし。続けたいんなら VC++ スレ行ってくれ。
・・・あれ? VC++ の専用スレは無いのか? Visual Studio ならあるみたいだけど。
764デフォルトの名無しさん:2009/02/06(金) 13:56:35
dllが解放されるときにshared_ptrが解放されてるだけじゃね?
765デフォルトの名無しさん:2009/02/06(金) 14:03:09
>>761
とりあえず vector を生配列に置き換えるとか、手動で delete するとか、
どの部品で問題が起こるのか切り分けるといいかもしれない。

T::create() が怪しい。

問題とは関係ないだろうけど、名無し share_ptr は使わないようにおぼえておいたほうがいい。
http://www.boost.org/doc/libs/release/libs/smart_ptr/shared_ptr.htm#BestPractices
> Avoid using unnamed shared_ptr temporaries to save typing; ...

とか考えてみたけど、 >763 で FA だな。
766632:2009/02/06(金) 21:37:52
いろいろ試行錯誤してたら遅くなりました。だいぶ切り分けられました。
vectorは関係ないみたいです。

thread A:
 shared_ptr<Test> test; // これをDLL側で構築したい
 ThreadB(test); // スレッドを作成してThreadB::runをコール
---
struct ThreadB {
 shared_ptr<Test> test_;
 ThreadB(shared_ptr<Test>& test) : test_(test) {} // testを受け取る
 void run(void) { dll_func(test_); } // スレッドが走るとDLLを呼ぶ
};
---
void dll_func(shared_ptr<Test>& test) {
 test.reset(new Test); // これがアウト
}

ThreadBから抜けるときに例外が発生します。
shared_ptrの使い方間違ってるでしょうか。

>>765
> Avoid using unnamed shared_ptr temporaries to save typing; ...
引数の評価の途中で例外が発生するとメモリリークが発生するという話は
Effective C++にもあって、ちょうどそこを昨晩読んだところでした。

>>763
DLL間のオブジェクトのやり取りに便利というのがshared_ptrのもう一つの有効な使い道みたいなので(昨晩知りました)
ここで勘弁して下さい。

767デフォルトの名無しさん:2009/02/06(金) 23:52:30
template<typename T> struct test{ struct type{}; };
template<typename T> void f(){
 //VC++ではコンパイルできない。typenameを除くとコンパイルできるが今度はgccではコンパイルできなくなる。
 struct fn{ static void g(){ typename test<T>::type i; } };
}
int main(){
 f<int>(); return 0;
}

コンパイラの挙動としてはどちらが正しいのでしょうか?
768デフォルトの名無しさん:2009/02/07(土) 00:14:06
g++
769デフォルトの名無しさん:2009/02/07(土) 00:28:59
根拠は?
770デフォルトの名無しさん:2009/02/07(土) 00:38:03
規格読め
771デフォルトの名無しさん:2009/02/07(土) 00:43:55
それがコンパイルできないのは古いVCまでだよ
772デフォルトの名無しさん:2009/02/07(土) 00:55:57
C++でJavaでいうユーティリティ(静的メンバだけのクラス)を
作りたいんだけど、C++だとやり方が
・クラスの静的メンバ関数として定義
・名前空間内で関数定義
の2つ思いつくが設計上どういう違いがあるのかわからん
オープンソースだと後者をよく見かけるんだが、これがC++風なの?
773デフォルトの名無しさん:2009/02/07(土) 01:06:36
普通の関数をわざわざメンバ関数にする必要は無いかと。
まあ、using を禁止する意味で、敢えてメンバ関数にするというのなら分かるけど。
774デフォルトの名無しさん:2009/02/07(土) 01:08:23
もちろん、完全にユーティリティの場合の話だからね。
静的メンバ関数自体は有用なものだ。
775デフォルトの名無しさん:2009/02/07(土) 01:16:53
>>774
なるほど。
C++だとJavaのようになんでもクラス化は間違い?
プログラミング言語C++、effective C++は読んだのだけど
これは設計に関しては今でも通じる?
最近のC++のプログラミングスタイルを学びたいんだけど
地道にオープンソース読んでいくしかないのかな
776デフォルトの名無しさん:2009/02/07(土) 01:59:29
最近のプログラミングスタイルならboostだろ JK
777デフォルトの名無しさん:2009/02/07(土) 02:13:10
>772
クラス
 ・アクセス制御ができる
 ・継承ができる
 ・テンプレートの引数とかtypedefで使える
  --> Traitsなんかを参照。
名前空間
 ・開いているので別の所で関数などを追加できる。

といった特徴があるので適材適所で。
778デフォルトの名無しさん:2009/02/07(土) 02:16:33
>>775
そもそも Java は普通の関数を作れないから仕方が無い
779777:2009/02/07(土) 02:18:20
Traitsの所はなんか変だな。ちょっと修正&追加
 ・テンプレートの引数とかtypedefで使える
  --> Mix-in(Policy)とかに使える。
 ・クラステンプレートにできる
  --> テンプレートの特殊化で色々なことができる。Traitsなんかを参照。

780デフォルトの名無しさん:2009/02/07(土) 03:57:35
>>766
スレッドまで絡んでるのか。こんどはスレッド使わずにやってみればいいんじゃね?

boost::shared_ptr の話なら Boost スレに行ってもらったほうがいいような気がする。
っていうか、なんで一番的確と思われる >763 のアドバイスを無視してるの?
781デフォルトの名無しさん:2009/02/07(土) 15:52:17
delete/delete[]についての疑問なのですが

「配列へのポインタ」を「配列でないポインタ」へキャストした場合、"delete"と"delete[]"のどちらを使えばよいのでしょう?

char *p0 = new char[4];
int *p1 = (int *)p0;

delete[] p1; なのか delete p1; なのか
782デフォルトの名無しさん:2009/02/07(土) 15:54:16
delete[] (char*)p1;
783デフォルトの名無しさん:2009/02/07(土) 15:55:57
>>781
その p1 はその型のままでは何にも使えない。
784デフォルトの名無しさん:2009/02/07(土) 15:56:43
delete[] (char *) p1;
785デフォルトの名無しさん:2009/02/07(土) 15:57:43
>「配列へのポインタ」を「配列でないポインタ」へキャストした場合
それらの違いは何を想定している? その以下の例とは異なるようだが。
786デフォルトの名無しさん:2009/02/07(土) 15:58:07
>>782dクス
つまりnewの際の型にしてやる必要があるということでしょうか
delete[] p1; も delete p1; もNG?
787デフォルトの名無しさん:2009/02/07(土) 15:59:20
>>786
そもそもそのキャスト自体が異常。どうしてもやりたいならreinterpret_castを使え。
788デフォルトの名無しさん:2009/02/07(土) 16:00:16
>>785
例は簡略化してますが、バイト列を構造体にキャストして利用する場合などです。
789デフォルトの名無しさん:2009/02/07(土) 16:01:56
ダメだこりゃ。
790デフォルトの名無しさん:2009/02/07(土) 16:08:59
>>783
たしかにそうですね(^^;
p1にアドレス入れないといけませんが64bit幅だと4バイトどこかを破壊する事に
791デフォルトの名無しさん:2009/02/07(土) 16:11:23
freeはvoid*だったけどdeleteは型が意味もつんかな
new/deleteのアルゴリズムどっかに書いてないか?
792デフォルトの名無しさん:2009/02/07(土) 16:14:07
>>790 いちおう言っておくが、 int としてもアクセスできる保証は無いよ。
793デフォルトの名無しさん:2009/02/07(土) 16:17:08
じゃあ、お前は何を保証するんだよ
794デフォルトの名無しさん:2009/02/07(土) 16:18:52
俺じゃなくて、規格が char* にキャストで戻せば元通りに使えることを保証するよ。
795デフォルトの名無しさん:2009/02/07(土) 16:46:54
>>791
new[]で確保したメモリは、こうなってるみたいよ。ポインタは先頭オブジェクトを指してる。
| 数 | obj | obj | obj | obj |
796デフォルトの名無しさん:2009/02/07(土) 16:48:17
実装依存
797デフォルトの名無しさん:2009/02/07(土) 17:10:31
格納の仕方は違うだろうけど、795からわかることは「delete呼ぶにはオブジェクトサイズが必要」ってことだな。要素数はいらないということも。
798デフォルトの名無しさん:2009/02/07(土) 17:20:20
>>795からそんなことがわかるのお前だけ。
799デフォルトの名無しさん:2009/02/08(日) 13:11:38
gcc 3.4.5を使っています。
以下のコードはどうしてVC++では通るのにgcc 3.4.5では通らないのでしょうか?
テンプレートクラス内のテンプレートクラスの特殊化は駄目なんでしょうか?
template<typename Expr>
struct testyhand{
 template<unsigned int i>
 struct test;

 template<>
 struct test<0>{
  enum{ value = 0 };
 };

 template<>
 struct test<1>{
  enum{ value = 1 };
 };
};
800デフォルトの名無しさん:2009/02/08(日) 14:16:39
>>799
エラー内容は?
801デフォルトの名無しさん:2009/02/08(日) 14:18:38
>>800
error: explicit specialization in non-namespace scope `struct testyhand<Expr>'
error: enclosing class templates are not explicitly specialized
error: template parameters not used in partial specialization:
error: `Expr'
error: explicit specialization in non-namespace scope `struct testyhand<Expr>'
error: enclosing class templates are not explicitly specialized
error: template parameters not used in partial specialization:
error: `Expr'
802デフォルトの名無しさん:2009/02/08(日) 15:20:51
803デフォルトの名無しさん:2009/02/08(日) 15:27:20
>>802
ぁーそれ俺も最近悩んだわ。
特殊化はクラススコープの外で書いてあげないと怒られる。
804デフォルトの名無しさん:2009/02/08(日) 15:54:35
規格でいえば 14.5.2 あたりからかな
805デフォルトの名無しさん:2009/02/08(日) 20:38:28
VC++2008です。ソース分割された静的変数を任意位置で初期化したいんですがどうすればいいですか?
ソースは以下のようになっています。
//main.cpp
#include "src.h"
int main(){
  init();
  loop();
}
//src.h
class Test{
  static int num;  //private
}
int Test::num = otherclass::getnum();  //これをinit();の直後に実行したい
806デフォルトの名無しさん:2009/02/08(日) 20:43:49
静的メンバ変数の初期化は、
各翻訳単位内では実体定義の順番通りに実行される。
翻訳単位間での実行順は未規定。
これらの初期化の実行は、main 関数より前に行われる。

要約すると、init(); の後に初期化処理を記述するしか無い。
807デフォルトの名無しさん:2009/02/08(日) 20:44:44
こういう場合は Singleton パターンが有効。
Singleton パターンでググれ。
808デフォルトの名無しさん:2009/02/08(日) 20:56:42
>>806-807
迅速な回答ありがとうございます。
早速Singleton パターンで調べてみます。
809デフォルトの名無しさん:2009/02/09(月) 02:26:26
こっちの方が有効。静的メンバ変数じゃなくてメンバ関数の中に静的ローカル変数を用意してそれを戻す。
ttp://ja.wikibooks.org/wiki/More_C%2B%2B_Idioms/%E5%88%9D%E5%9B%9E%E4%BD%BF%E7%94%A8%E6%99%82%E7%94%9F%E6%88%90(Construct_On_First_Use)
初出はなんだっけ?
810デフォルトの名無しさん:2009/02/09(月) 08:50:57
>>809
マルチスレッドでも大丈夫だっけ?
811632:2009/02/09(月) 11:24:54
>>780
マルチスレッドとdllとshared_ptrの問題みたいなので他スレで聞いてみます。
>>763というのはデバッガ使えという話ですか?
追ってはいるんですが、shared_ptrの参照カウントを減らすところで
すでにdeleteされているものをdeleteしようとしていることくらいしか分からないです。
とりあえず、スレッドBが呼んだdllで確保したメモリをスレッドAで解放しなければ
正常に動作するところまでは確認しました。


812632:2009/02/09(月) 12:53:22
>>811 は少し不正確でした。無視して下さい。
「すでにdeleteされているものをdeleteしようとしている」わけではなくて
「deleteするところで例外が発生する(delete先はこの時点で生きてるっぽい)」でした。
813デフォルトの名無しさん:2009/02/09(月) 13:00:53
デストラクタで例外でも投げてるとか
814632:2009/02/09(月) 13:14:07
>>813
正確には <memory> 内で
~shared_ptr ⇒ _Ptr_base::_Decref ⇒ _Ref_count_base::_Decref
で、_Ref_count_base::_Destroyが_Ref_count_base::_Getptrの返り値を
deleteしようとするところで例外が起きます。
参照カウントはこの直前で1から0に減らされてます。
_Getptrの返り値は0ではないです。
スレッドを使ってもDLLを使わなければOK、DLLを使ってもスレッドを使わなければOKでした。
マルチスレッドスレで聞いてみます。
815デフォルトの名無しさん:2009/02/09(月) 14:44:53
ランタイムエラー R6025 pure virtual function call
の再現方法(エラーの発生手順)をご存じありませんか?


調査してみたところ、
無効なポインタを使用して関数が呼び出された場合に発生する
という情報があったので試してみたのですがR6025は発生しませんでした。
816デフォルトの名無しさん:2009/02/09(月) 15:00:52
>>815 pure virtual function を call するんだ。
817デフォルトの名無しさん:2009/02/09(月) 15:02:02
>>815
サンプルコード
class A;
void fcn( A* );
class A {
  public:
  virtual void f() = 0;
  A() { fcn( this ); }
};
class B : A {
  void f() { }
};
void fcn( A* p ){ p->f();}
B b;
void main(){}
818デフォルトの名無しさん:2009/02/09(月) 16:41:09
>>809
なるほど、すっきりと書く事ができました。ありがとうございました
819デフォルトの名無しさん:2009/02/09(月) 18:12:26
クラスで動的な部分が値を保持するいくつかの変数だけだとしたら
他のメンバは、特に関数は全て静的にするのが常識なんでしょうか?
やっとこの辺が理解できてstaticを付けまくりたくてたまりません
820デフォルトの名無しさん:2009/02/09(月) 20:46:16
そんな常識はありません。
メンバ変数にアクセスしない関数を静的にするのは一つの見識ですが。
尤も、そんな関数ばかりならnamespaceにすることも検討すべきかと。
821デフォルトの名無しさん:2009/02/09(月) 21:23:36
普通はメンバ関数は大抵メンバ変数にアクセスする処理ばかりになるはず。
メンバ変数にアクセスしないものもたまーに存在するが、そう多くないはず。
822デフォルトの名無しさん:2009/02/09(月) 21:24:52
メンバ変数を参照しない関数は高確率でstaticにしてるな
823デフォルトの名無しさん:2009/02/09(月) 22:11:37
メンバ変数を参照してても関数内で動的クラスの動的変数を参照する記述なら問題なくないですか?
824デフォルトの名無しさん:2009/02/09(月) 22:19:14
まず正しく用語を使え。
いらぬ誤解を招く。

そしてコンパイルとおらねえだろ。
825デフォルトの名無しさん:2009/02/09(月) 22:23:22
おそらくインスタンスと言いたいのだろうな
826デフォルトの名無しさん:2009/02/09(月) 22:25:38
これコンパイル通らないのか
納得
staticはメンバ変数にアクセスしない関数だけだね
827デフォルトの名無しさん:2009/02/10(火) 00:32:25
例えばstd::stringのような有名なクラスを継承した自作クラスを作って
ライブラリにしようとした場合、そのstd::stringは
仮想継承させておくべきなの?
それとも仮想継承にはしないでおいた方が良いの?
なんか、既存の文化とか慣習とかあります?
828デフォルトの名無しさん:2009/02/10(火) 00:35:29
ない。仮想継承は動的に継承を解決する。
ライブラリ内で自作stringが仮想継承を必要とするならばそうするべきだが、
別にそれ以外のケースで文化とか慣習はない。
829デフォルトの名無しさん:2009/02/10(火) 00:39:30
>>827
慣習っていうならそもそもSTLを継承はしない
830デフォルトの名無しさん:2009/02/10(火) 00:39:47
参照透過性のある関数を動的に生成したいのですが(現時点ではインタプリタっぽい実装になっているので高速化したい)、使うのにベターなライブラリやインラインアセンブリの命令などはありますか?
831デフォルトの名無しさん:2009/02/10(火) 00:40:41
>>828
>>829
ふーむ、なるほど。
ありがとうございます。
832デフォルトの名無しさん:2009/02/10(火) 00:51:49
BaseクラスがテンプレートクラスBase<type_T>だとします。
template <typename type_T>
class Base
{〜}
このときBaseを継承したDerivedクラスを考え、これもテンプレートクラスにします。
template <typename type_T>
class Derived : public Base
{〜}
…ここでDerived<type_T>のメンバ関数の中からBase<type_T>のメンバ関数foo()を呼ぼうとしたらコンパイルエラーになりました。
そこでいちいちBase<type_T>::foo()の様に指定したらうまくいったのですが、
これ(Base<type_T>::)って省略できないものなのですか?
テンプレートじゃなきゃできますよね?
833832:2009/02/10(火) 00:52:22
テンプレートクラス
→→クラステンプレートです
834デフォルトの名無しさん:2009/02/10(火) 00:54:54
typedef Base<type_T> base;
base::foo();
835デフォルトの名無しさん:2009/02/10(火) 00:59:40
2番目の宣言がおかしくね。

template<typename type_T>
class Derived : public Base<type_T>

じゃね? 省略したらどうなるんだろう。
836832:2009/02/10(火) 00:59:55
趣旨がわかりにくくて済みません。
Derived<type_T>のメンバ関数の中bar()からBase<type_T>のメンバ関数foo()を呼ぼうとしている状況です。
つまり
template <typename type_T>
void Derived<type_T>::bar()
{
foo();
}
としたらコンパイルエラーになりました。
そこでいちいち
template <typename type_T>
void Derived<type_T>::bar()
{
Base<type_T>::foo();
}
の様に指定したらうまくいったのですが、
これ(Base<type_T>::)って省略できないものなのですか?
テンプレートじゃなければ継承しているんですから要らないですよね?
837デフォルトの名無しさん:2009/02/10(火) 01:01:28
通る
template <typename T> struct Base {
void foo() {}
};
template <typename T> struct Derived : public Base<T> {
void bar() { foo(); }
};
838832:2009/02/10(火) 01:01:51
>>835
すみませんそれ付けていました。
書き間違いです。
(試しに省略したらさすがにコンパイルエラーでした。)
839832:2009/02/10(火) 01:02:33
>>837
あれれ??
ちょっと待っててください。
840デフォルトの名無しさん:2009/02/10(火) 01:10:54
BaseがTを使用してなければ通るんじゃね。
Base<T>じゃなくてBaseとして宣言されたstructを呼び出してるだけなんだし。

省略はできないし、すると意味が違うだろう。

Base<void>とBase<T>とBase<A>は全部別コードになるよ。
841832:2009/02/10(火) 01:19:56
再現性を確認しました。
template <typename type_T>
class Base
{
public:
void foo();
};

template <typename type_T>
class Derived : public Base<type_T>
{
public:
void bar();
};

template <typename type_T>
void Derived<type_T>::bar()
{
//foo();
//Base<type_T>::foo();
}
です。本文中で
Derived<int> hoge;
Derived<double> piyo;
の様にインスタンス化させています。この条件の下で、
foo();
でも
Base<type_T>::foo();
でも両方ともBCCではコンパイルOKですが、g++では前者がエラーで後者がOKです。
error: there are no arguments to `foo' that depend on a template parameter, so a declaration of `foo' must be available
error: (if you use `-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)
842デフォルトの名無しさん:2009/02/10(火) 02:58:23
C++ FAQ Lite にも出てる問題だね。

[35] Templates Updated! , C++ FAQ Lite
[35.19] Why am I getting errors when my template-derived-class uses a member it inherits from its template-base-class? Updated!
http://www.parashift.com/c++-faq-lite/templates.html#faq-35.19

対策は >>834 とか、 FAQ で出てる
this->foo();
とか
using Base<type_T>::foo;
あたり。
843デフォルトの名無しさん:2009/02/10(火) 11:53:26
規格14.6.1 の paragraph 3 だな。

大域名前空間にfooを定義すれば、そちらが呼ばれる。
844デフォルトの名無しさん:2009/02/10(火) 12:52:36
.hppってなんですか?
845デフォルトの名無しさん:2009/02/10(火) 13:01:50
ファイル名の一部。拡張子。
C++言語的には何の関係も無い。
846デフォルトの名無しさん:2009/02/10(火) 13:09:19
>>845
嘘つくな

>>844
C++用のヘッダーファイルの拡張子
847デフォルトの名無しさん:2009/02/10(火) 13:19:12
>>846
>>845
>C++言語的には
848デフォルトの名無しさん:2009/02/10(火) 13:20:43
あたし>>846じゃないけど
>>845はひどいと思う
849デフォルトの名無しさん:2009/02/10(火) 13:52:10
>>845 の「C++言語的」 というのが「言語仕様」のつもりなら
確かにファイル名がどうとかまったく関係ない。
/*
 でも、拡張子がファイル名の一部かどうかは環境次第なので
 >>845 は誤り
*/

一般的な解釈では >>846 の通り。
850デフォルトの名無しさん:2009/02/10(火) 14:57:31
定義も含むのがhppで宣言だけならhだと思ってた
851=841=832:2009/02/10(火) 15:31:23
難しいですねテンプレート。
このあたり直感的でないのはまだテンプレートが新しめの機能だからですかね?
私方式の
Change the call from f() to B<T>::f().
だと注意書きがありまして
Note however that this might not give you what you want if f() is virtual, since it inhibits the virtual dispatch mechanism.
だそうですが、これってどういう事ですか?
f()が仮想関数としてB<T>でもD<T>でも定義されているときに、
B<T> *p=new D<T>;
p->f();
とすると、本来なら仮想関数なので期待通りにD<T>::f()が呼ばれて欲しいが、記述上残念ながらB<T>::f()が呼ばれてしまいますよ
ってことですか?

852デフォルトの名無しさん:2009/02/10(火) 16:19:26
853デフォルトの名無しさん:2009/02/10(火) 16:28:28
ありがとうございます。
連続で聞いて申し訳ないですが
Change the call from f() to this->f().

Since this is always implicitly dependent in a template, this->f is dependent and the lookup is therefore deferred until the template is actually instantiated, at which point all base classes are considered.
って言うのは、
this->が解決されるのがD<T>が具体的にインスタンス化された時だから、そのときにはもう親クラスのfoo()が継承されているから大丈夫なんですよ
ってことですか?
854デフォルトの名無しさん:2009/02/10(火) 19:30:05
>>853
そんなてめぇが疑問に思ってるような
コードを人様に見せる場面で使うんじゃねぇウンコ
855デフォルトの名無しさん:2009/02/10(火) 21:23:20
>853
ちょっと違う。
template 中の名前解決は 2 回に分けて行われる(これは two phase lookup と言われている)。
具体的には宣言された時と、インスタンス化された時の 2 回。
テンプレート型パラメータに依存している名前はインスタンス化された時に、それ以外は宣言時に解決される。
f() はテンプレート型パラメータに依存していないため宣言時に名前が解決され、結果として、テンプレート型パラメータ依存の
基本クラス B<T> まで見に行かない(見に行くのはインスタンス化された時だから)。
this->f() にすると、this がテンプレート型パラメータ依存であるため、this->f() もテンプレート型パラメータ依存となる。
結果、f の名前解決がインスタンス化時点となり、テンプレート型パラメータ依存の B<T> の中まで探しに行くことになる。
856デフォルトの名無しさん:2009/02/10(火) 22:01:00
857デフォルトの名無しさん:2009/02/10(火) 22:10:09
>>854
別に「各自の自慢のコーディングを人様に教え合うスレ」ってわけじゃないから良いじゃないですか。
むしろ自分しか見ないコードの中で自分が疑問に思っているコーディングをしたらひんしゅくすら買えない謎のバグを仕込みかねませんし。

>>855
ありがとうございます。
本気で分かりやすかったです!
858デフォルトの名無しさん:2009/02/10(火) 22:10:54
>>856
すみません投稿中で見てませんでした。
今から見てみます。
ありがとうございます。
859デフォルトの名無しさん:2009/02/10(火) 22:47:25
>>857
使う機会がねぇだろボケ
860デフォルトの名無しさん:2009/02/10(火) 22:50:07
>>859
お前だけな
861埋め:2009/02/10(火) 22:56:11
埋め
862埋め:2009/02/10(火) 22:56:33
埋め
863埋め:2009/02/10(火) 22:56:54
埋め
864埋め:2009/02/10(火) 22:57:16
埋め
865埋め:2009/02/10(火) 22:57:37
埋め
866埋め:2009/02/10(火) 22:58:20
埋め
867埋め:2009/02/10(火) 22:58:28
埋め
868埋め:2009/02/10(火) 22:58:50
埋め
869デフォルトの名無しさん:2009/02/11(水) 01:34:07
相談スレで相談するなとかどんだけ。
870デフォルトの名無しさん:2009/02/11(水) 06:25:41
自分が理解できないものを見なかったことにしたかったのでしょう。その証拠にほら、埋め嵐。
871デフォルトの名無しさん:2009/02/11(水) 06:32:27
おもしろいな
もういっぺんいってやろう

>>853
そんなてめぇが疑問に思ってるような
コードを人様に見せる場面で使うんじゃねぇウンコ
872埋め :2009/02/11(水) 11:06:00
埋め
873埋め:2009/02/11(水) 11:06:24
埋め
874埋め:2009/02/11(水) 11:06:44
埋め
875埋め:2009/02/11(水) 11:07:12
埋め
876埋め:2009/02/11(水) 11:07:34
埋め
877埋め:2009/02/11(水) 11:08:19
埋め
878埋め:2009/02/11(水) 11:08:37
埋め
879埋め:2009/02/11(水) 11:08:58
埋め
880埋め:2009/02/11(水) 11:09:20
埋め
881デフォルトの名無しさん:2009/02/11(水) 11:12:03
埋めるな
882デフォルトの名無しさん:2009/02/11(水) 12:07:36
埋めてんじゃねーよ
883デフォルトの名無しさん:2009/02/11(水) 13:01:47
埋めるぞ
884デフォルトの名無しさん:2009/02/11(水) 13:41:55
ずいぶん可哀想な奴がいるな。
885埋め :2009/02/11(水) 14:54:40
埋め
886デフォルトの名無しさん:2009/02/11(水) 16:12:43
標準またはboostに数学の順列の数、組み合わせの数を求める関数はないですか?
887デフォルトの名無しさん:2009/02/11(水) 16:21:12
>>886
ないと思う
next_permutationで生成しながら数えれば

while (std::next_permutation(rng.begin(), rng.end())) count++;
888デフォルトの名無しさん:2009/02/11(水) 16:22:52
自分で計算する関数作ったほうがいいな。
公式あるし、オーバーフローに気をつければあとは楽。
889デフォルトの名無しさん:2009/02/11(水) 16:25:07
そんな難しいロジックじゃなさげだな
自分で作った方がパフォーマンス調整しやすいし作ってみれば?
890デフォルトの名無しさん:2009/02/11(水) 16:40:06
n 個のものから m 個を取り出す順列の数 n!/(n-m)!
891デフォルトの名無しさん:2009/02/11(水) 16:52:21
>>887-890
レスthx
boostには数学に関して結構マニアックな物まであるのに、ないとは意外でした。
簡単に実装できるものなので自分で書くことにします。
892デフォルトの名無しさん:2009/02/11(水) 19:22:54
すぐオーバーフローして使いどころが限られるから、
あるいは使い方がケースによってまちまちだからなのかねえ
893デフォルトの名無しさん:2009/02/11(水) 23:03:10
クラス設計で質問

メンバにオブジェクト持たせるとき、ポインタで持つのが当たり前?
STLのコンテナとかそのクラスのデフォルトコンストラクタが空とかなら直で持ってもいいんでしょうか
別に実装隠したいわけでもない場面でもpimplイディオムでやらなきゃいけないのかな
Javaと同じようにやろうとすると面倒くさすぎる
逆にクラスを使う人間にこういう事を考えさなくてよいよう、デフォルトコンストラクタは全クラスで定義すべき?


vectorメンバのsetterを下のやり方でやってるんだけど
もっと効率良いやり方あったらダメ出し下さい
void Foo::set_vec(const std::vector<int>& val){
vec_(val);
}
894デフォルトの名無しさん:2009/02/11(水) 23:12:55
>>893
速度で言うなら、中身がPOD型だから
resizeしてmemcpyする方法が使用可能ではある
895デフォルトの名無しさん:2009/02/11(水) 23:16:25
896デフォルトの名無しさん:2009/02/11(水) 23:20:03
>>893
ポインタで持たないと何が面倒なんだ?
vec_ = val じゃないの?
897デフォルトの名無しさん:2009/02/11(水) 23:22:24
>>891
>>892
もし作るならnCrは再帰を利用し、漸化式から作るようにした方がいいよ。
n!/(r!(n-r)!)でやると、あっという間に途中式(階乗の部分)がオーバーフローするけど漸化式を利用した方法ならそれなりに持ちこたえられるらしいです。
boostにない理由は分からないけど、まあたぶん、nCrにおいてどうせ作るならnやrが整数でない場合についても計算できるようなライブラリにしないとなんか不満な気がしてるとか?
んで難しくて実装できてないとか?
898デフォルトの名無しさん:2009/02/11(水) 23:30:27
C++(含0x)の標準ライブラリに多倍長演算って無いの?

899デフォルトの名無しさん:2009/02/11(水) 23:33:11
無いよ。
900デフォルトの名無しさん:2009/02/11(水) 23:34:36
そういうライブラリを作るのも面白いな
マルチコアを意識して作ったら、地味に早くなるものだろうか
901デフォルトの名無しさん:2009/02/11(水) 23:34:39
だめだなー
902デフォルトの名無しさん:2009/02/11(水) 23:36:38
>>898
マジで銀行とかどうしてんだよって思うな
俺が関わったときはなんかライブラリ使ってたけど
903デフォルトの名無しさん:2009/02/11(水) 23:36:44
>>896
ファクトリが定義されてないクラスをメンバにするとき
newとdelete書かなきゃいけないのが嫌なのです
単体テストクラスが書きずらくなりませんか?
コンテナみたいな汎用的なオブジェクトでいちいちそれを書くのも面倒くさいかな、と
あと vec_ = valだとvalの参照先が変わったらvec_も変わるんじゃないかな
904デフォルトの名無しさん:2009/02/11(水) 23:36:52
>>900
基本はテンプレートでお願い。勝手にスレッドとか作ったら死刑。
905デフォルトの名無しさん:2009/02/11(水) 23:39:26
redoとundo実装しろって言われたときにクラスを心底恨んだ
メンバはなるべく構造体で定義してからクラスにもたせる
906デフォルトの名無しさん:2009/02/11(水) 23:41:19
ホントに多倍長演算が無いのは謎。
あってもおかしくないだろうに。
907デフォルトの名無しさん:2009/02/11(水) 23:41:37
>>903
とりあえず delete 書くぐらいなら auto_ptr ぐらい使っとけ。
具体的なクラスを new するのが嫌なら引数でもらうようにしとけばいい。
コンテナを new するつもりならやめておけ。
vec_ = val はコピーだ。参照先とか関知しない。
908デフォルトの名無しさん:2009/02/11(水) 23:42:32
ReDo/UnDoの仕組みを構築するのは本当に疲れるよな
奇麗な差分を作らないと、メモリを圧迫するし
909デフォルトの名無しさん:2009/02/11(水) 23:42:34
要素型にデフォルトコンストラクタが無くてもコンテナは使えなかったっけ?
910デフォルトの名無しさん:2009/02/11(水) 23:44:43
>>907
STLコンテナ相手なんだからshared_ptrくらい挙げようよ。
今使うには微妙かもしれないだけどさ。
911デフォルトの名無しさん:2009/02/11(水) 23:48:05
自分のコードに delete が登場したらそのコードは間違っていると思って良いくらいです
って稲葉一浩氏がおっしゃってたよ。
Let's Boost - メモリ管理
http://www.kmonos.net/alang/boost/smartptr.html
912デフォルトの名無しさん:2009/02/11(水) 23:48:53
boost::ptr_vector
913デフォルトの名無しさん:2009/02/11(水) 23:49:44
質問なのですがvectorの特定の要素の削除ってどうやるんでしょうか
vector<int>::iterator it = find(v.begin(),v.end(),v[1]);v.erase(it,it);
じゃ動かないし
removeやremove_ifを使うと、重複値がある場合はそれも取り除かれてしまい
望んだ動作とは違うんです
914デフォルトの名無しさん:2009/02/11(水) 23:49:46
今まで参照カウントのshared_ptrが標準に無かったことも大きな間違いだな。
915デフォルトの名無しさん:2009/02/11(水) 23:49:47
>vec_ = val はコピーだ。参照先とか関知しない。
これはマジ?VC7,1だとこういうのは駄目だった気が。。
vector<vector<int> >
916デフォルトの名無しさん:2009/02/11(水) 23:49:57
思って良いくらいであって、間違いとは言ってない
917デフォルトの名無しさん:2009/02/11(水) 23:50:56
あ、erase(it)で動いた・・913は忘れてください。失礼・・
918デフォルトの名無しさん:2009/02/11(水) 23:51:14
>>897
パスカルの三角形を利用した再帰による実装は
オーバーフローの危険性は最も少ないけど、
バッファを用意して再計算を減らさないと遅いし、
nCr が必ず整数になることを利用して、こう実装した方が速い。
オーバーフローの危険性は多少増えるが、
n - r がそれなりに大きくないとそういう状況にはならないと思うし、
なんなら一時変数のサイズを増やせば良い。

r = 0 の時、
nCr = 1

r > 0 の時、
nCr = n!/(r!(n-r)!) = n!/((r-1)!(n-r+1)! * r/(n-r+1)) = nC(r-1) * (n-r+1)/r

unsigned int combi(unsigned int n, unsigned r)
{
 if (n < r) { return 0; }
 if (r > n / 2) { return combi(n, n - r); }

 unsigned int nCr = 1;
 for (int s = 1; s <= r; ++s) {
  nCr = nCr * (n - s + 1) / s;
 }
 return nCr;
}
919897:2009/02/11(水) 23:54:07
>>918
完成版サンクス。
問題はもう891さんがご覧になっていないかもしれぬと言うところだな。
920デフォルトの名無しさん:2009/02/12(木) 00:01:33
分岐は増えるが、>>918 のオーバーフロー安全性を
パスカルの三角形と同レベルにすることもできるぜ。

for (int s = 1; s <= r; ++s) {
 if (nCr % s == 0) {
  nCr /= s;
  nCr *= (n - s + 1);
 } else {
  nCr *= (n - s + 1) / s;
 }
}
921デフォルトの名無しさん:2009/02/12(木) 00:07:37
(n - s + 1) / s って常に整数なの?
922897:2009/02/12(木) 00:07:37
>>920
俺が軽い気持ちで書き込んだオーバーフローの話題にみんな何でこんなに付いてきてくれるんだ?
なんかスマン
923デフォルトの名無しさん:2009/02/12(木) 00:08:44
>>921
常に整数じゃないから分岐してるんじゃん。
924デフォルトの名無しさん:2009/02/12(木) 00:10:11
じゃあ、nCr % s != 0 のとき、
(n - s + 1) / s って常に整数なの?
925デフォルトの名無しさん:2009/02/12(木) 00:10:47
パスカルの三角形っていってるのはこれのこと?
int com(int n,int k){
 if(n<k)return 0;
 else if(n==k||k==0)return 1;
 return com(n-1,k)+com(n-1,k-1);
}
俺はコンテナの並び替えとかのがほしいから
こんなのを自作して使ってる。効率とかはあんま考えたことがないので
よくわからんが
string s="abcde";
string c="";
void com(int p,int k){
if(k==0){cout << c << endl;return;}
if(p>=s.size())return;
c+=s[p]; com(p+1,k-1); c.erase(c.end()-1);
com(p+1,k);
}
926デフォルトの名無しさん:2009/02/12(木) 00:11:23
>>924
常に整数だよ。
整数じゃなかったら、nCs が整数にならないじゃん。
927デフォルトの名無しさん:2009/02/12(木) 00:12:28
>>926
>整数じゃなかったら、nCs が整数にならないじゃん。

いや、だからおかしいだろ、って言外に言ってるのだが。
928デフォルトの名無しさん:2009/02/12(木) 00:12:55
ついでpermutation
next_permutationは重複値がある時少しめんどうだから
こっち使ってる
void perm(string&a,int n){
if(n==a.size()-1){cout << a << endl;return;}
for(int i=n;i<a.size();++i){
swap(a[i],a[n]);
perm(a,n+1);
swap(a[i],a[n]);
}
}
929デフォルトの名無しさん:2009/02/12(木) 00:13:24
>>926
そんな証明の循環みたいなこと言われても
930デフォルトの名無しさん:2009/02/12(木) 00:15:25
下降階乗冪で考えるとわかりやすいよ
931デフォルトの名無しさん:2009/02/12(木) 00:16:02
void niwatori() {
 tamago();
}

void tamago() {
 niwatori();
}
932デフォルトの名無しさん:2009/02/12(木) 00:17:34
>>927
nCr と (n - s + 1) のどちらも s の倍数でない場合もあるかもしれないもんな。
933デフォルトの名無しさん:2009/02/12(木) 00:19:49
>>932
確かに・・・。
なら、nCr と s の最大公約数を求める処理を挟む必要があるか。
934デフォルトの名無しさん:2009/02/12(木) 00:20:09
ええぃアルゴリズムスレでやれ。
935デフォルトの名無しさん:2009/02/12(木) 00:23:27
これでいいね。はい、終了。

for (int s = 1; s <= r; ++s) {
 unsigned int d = gcd(nCr, s);
 nCr /= d;
 nCr *= (n - s + 1) / (s / d);
}
936デフォルトの名無しさん:2009/02/12(木) 00:24:06
n=3, r=3
nCr=1, s=1 → nCr=1/1 → nCr=1*(3-1+1)=3
nCr=3, s=2 → nCr=3*((3-2+1)/3)=3*(2/3) ここで (n - s + 1) / sは整数ではない。
937デフォルトの名無しさん:2009/02/12(木) 00:25:29
if (r > n / 2) { return combi(n, n - r); }

これが見えんのか
938デフォルトの名無しさん:2009/02/12(木) 00:29:08
>>935
(n - s + 1) / (s / d) って常に整数なの?
939デフォルトの名無しさん:2009/02/12(木) 00:29:16
それに nCr % s == 0 のケースじゃん
940デフォルトの名無しさん:2009/02/12(木) 00:30:02
>>938
常に整数だよ。
整数じゃなかったら、nCs がどうやっても整数にならないじゃん。
941デフォルトの名無しさん:2009/02/12(木) 00:31:03
>>940
>整数じゃなかったら、nCs がどうやっても整数にならないじゃん。

いや、だからおかしいだろ、って言外に言ってるのだが。
942デフォルトの名無しさん:2009/02/12(木) 00:31:12
>>941
もうそのネタはいいよ
943デフォルトの名無しさん:2009/02/12(木) 00:31:55
>>897,918
数学的には簡単なのに、実装するとなると色々考えないといけないんですね。
とても勉強になりました。
944デフォルトの名無しさん:2009/02/12(木) 00:32:20
正しいと主張するなら、証明しろよ
945デフォルトの名無しさん:2009/02/12(木) 00:37:35
まず前提として、nCr * (n - s + 1) / s は必ず整数になると保証されている。
この式の結果は nCs に相当するからだ。これは整数だ。
つまり、nCr * (n - s + 1) は必ず s で割り切れる。

ここで、s = de, d = gcd(nCr, s) と分解する。
nCr (n - s + 1) / s = nCr (n - s + 1) / de = (nCr / d) (n - s + 1) / e

d は nCr と s の最大公約数なのだから、
e でも e の素因数でも nCr / d を割り切る事は出来ない。
従って、この式の結果が整数になるためには、
(n - s + 1) が e = s /d で割り切れる必要がある。
946デフォルトの名無しさん:2009/02/12(木) 00:40:15
>>945 の nCr ってのはあくまで一時変数名だから
そこんとこ誤解すんなよ
947886:2009/02/12(木) 00:45:35
リロードしないで>>943書いたらレスが大量に・・。
じっくり考えて読まないと理解できそうもないので、また明日読むことにします。
ありがとうございました。
948デフォルトの名無しさん:2009/02/12(木) 00:53:02
折角証明したのに >>944 は音沙汰無しかよ
949デフォルトの名無しさん:2009/02/12(木) 00:56:37
>>945
おk
950デフォルトの名無しさん:2009/02/12(木) 01:01:11
>>945
>まず前提として、nCr * (n - s + 1) / s は必ず整数になると保証されている。
>この式の結果は nCs に相当するからだ。

この証明して
951デフォルトの名無しさん:2009/02/12(木) 01:31:11
音沙汰無しなので、>>945の前提は成り立たず、>>945の証明は無効です。
952930:2009/02/12(木) 01:35:11
>>920のコードが間違ってるんだよね。
nCr *= (n - s + 1) / s;が間違いで
nCr = nCr * (n - s + 1) / s;が正しい

nCr * (n-s+1)/s;は整数になるが
(n-s+1)/s;は割り切れない時もある
953デフォルトの名無しさん:2009/02/12(木) 01:56:49
結局正しいコードは>>918もしくは>>920を修正してこうなる。
unsigned combi(unsigned n, unsigned r)
{
if (n<r) return 0;
if (r>n/2) return comb(n, n-r);
unsigned ncr = 1;
const unsigned m = n-r;
for (int s=1; s<=r; ++s) {
if (ncr%s == 0) {
ncr /= s;
ncr *= (m+s);
} else {
ncr = ncr * (m+s) / s;
}
}
return ncr;
}
954デフォルトの名無しさん:2009/02/12(木) 02:00:04
次スレはこれでいいの?作り直すの?
C++相談室 part66
http://pc11.2ch.net/test/read.cgi/tech/1231640498/
955デフォルトの名無しさん:2009/02/12(木) 02:00:58
それでいいよ
956930,953:2009/02/12(木) 02:19:57
下降階乗冪で考えると5C3は(5*4*3)/(3*2*1)で表すことが出来る。これを以下のように表記する。
543
321
でこれを計算するには上段の数字を右から掛けていき、その都度下段の数字で割ればよいこれをコードに起こすと
const unsigned m = n-r;
unsigned ncr = 1;
for (int s=1; s<=r; ++s)
ncr = ncr * (m+s) / s;
ここで問題になるのが ncr * (m+s) / sは整数になるのかどうかということだが先ほどの
543
321
を思い出す。右側から計算していくので
3
1
を計算することになるがこれは(3)/(1)つまり3C1の組み合わせの表記に等しく、組み合わせの数は整数である。次に
43
21
となるがこれも(4*3)/(2*1)となり4C2の組み合わせに等しい。
右側から見ていくとすべてが何らかの組み合わせの数に等しくなるため ncr * (m+s) / sは整数になる。
ちなみにncr * (m+s) / sと>>918のコードのnCr * (n - s + 1) / sとの違いは今までのものを
345
321
に並べ替えただけであり右から見ていけば(5)/(1)で5C1,(5*4)/(2*1)で5C2,(5*4*3)/(3*2*1)で5C3と全て組み合わせになるため
nCr * (n - s + 1) / sは同じく整数であるといえる。
957デフォルトの名無しさん:2009/02/12(木) 03:10:25
>>951
呆れてものも言えなかったんだよ。
>>918 に書いてある事をなんでもう一度言う必要があるんだ。
958デフォルトの名無しさん:2009/02/12(木) 03:19:51
>>956
そんなこと考えなくても、組み合わせ数は定義から整数になって当然。

冪で表現すると整数になると一見分かり辛いかもしれないが、
パスカルの三角形を思い出せば、
全ての組み合わせ数は 0C0 = 1 の和に展開できるのだから、
整数になると簡単に証明できる。

パスカルの三角形は
nC0 = 1 = (n-1)C0
nCn = 1 = (n-1)C(n-1)
nCr = (n-1)Cr + (n-1)C(r-1)  (0 < r < n)
の関係を表にしただけのもの。
n が 0 になるまで展開すれば最終的に 0C0 の和になることはすぐ分かる。
959930:2009/02/12(木) 09:45:13
>>953だとオバーフローのしやすさに変わりないからncr%sの分岐は意味ないくて
>>933が言うようにgcd使わないとダメなのかー。結局自分がよくレスを読めてなかったのか。
960デフォルトの名無しさん:2009/02/12(木) 11:56:37
ステップ数を正確に数える方法は?
改修ステップ数を正確に数える方法は?
961デフォルトの名無しさん:2009/02/12(木) 14:20:29
>>958
組み合わせの数を別の整数で割ったものが整数かという話だろ
962デフォルトの名無しさん:2009/02/12(木) 20:26:29
あ〜ぁ、また重複させちゃって。
どうする?
俺としては早漏スレより、新しいスレの方が好きだけど、
みんな似合わせるよ。
963デフォルトの名無しさん:2009/02/12(木) 21:08:13
part63が二つあったから、もし新しいスレを建てるんだったらpart67かな。
964デフォルトの名無しさん:2009/02/12(木) 21:14:19
part XX いらなくね?
965埋め:2009/02/12(木) 21:17:22
埋め
966埋め:2009/02/12(木) 21:17:44
埋め
967埋め:2009/02/12(木) 21:18:09
埋め
968埋め:2009/02/12(木) 21:18:39
埋め
969埋め:2009/02/12(木) 21:19:09
埋め
970埋め:2009/02/12(木) 21:19:27
埋め
971埋め:2009/02/12(木) 21:19:48
埋め
972埋め:2009/02/12(木) 21:20:10
埋め
973埋め:2009/02/12(木) 21:20:32
埋め
974埋め:2009/02/12(木) 21:21:04
埋め
975埋め:2009/02/12(木) 21:21:36
埋め
976埋め:2009/02/12(木) 21:22:32
埋め
977埋め:2009/02/12(木) 21:22:53
埋め
978埋め:2009/02/12(木) 21:25:41
埋め
979埋め:2009/02/12(木) 21:26:03
埋め
980埋め:2009/02/12(木) 21:26:25
埋め
981埋め:2009/02/12(木) 21:26:46
埋め
982埋め:2009/02/12(木) 21:27:08
埋め
983埋め:2009/02/12(木) 21:27:41
埋め
984埋め:2009/02/12(木) 21:28:02
埋め
985埋め:2009/02/12(木) 21:28:09
埋め
986埋め:2009/02/12(木) 21:28:31
埋め
987埋め:2009/02/12(木) 21:28:52
埋め
988埋め:2009/02/12(木) 21:29:14
埋め
989埋め:2009/02/12(木) 21:29:28
埋め
990埋め:2009/02/12(木) 21:30:07
埋め
991埋め:2009/02/12(木) 21:31:03
埋め
992デフォルトの名無しさん:2009/02/12(木) 21:32:11
うm
993埋め:2009/02/12(木) 21:35:34
埋め
994埋め:2009/02/12(木) 21:35:56
埋め
995埋め:2009/02/12(木) 21:36:20
埋め
996埋め:2009/02/12(木) 21:36:42
埋め
997埋め:2009/02/12(木) 21:37:06
埋め
998埋め:2009/02/12(木) 21:37:30
埋め
999デフォルトの名無しさん:2009/02/12(木) 21:37:52
999
1000デフォルトの名無しさん:2009/02/12(木) 21:38:06
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。