C++相談室 part63

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

前スレ
C++相談室 part62
http://pc11.2ch.net/test/read.cgi/tech/1211900039/
2デフォルトの名無しさん:2008/07/26(土) 02:51:39
■基本■
[C++ FAQ]
 http://www.parashift.com/c++-faq-lite/
 http://www.bohyoh.com/CandCPP/FAQ/ (日本語)
  Cとその仕様を比較しながらの解説なので分かりやすい。
  ***** 質問の前に必ずこの二つに目を通してください *****
[C/C++ リファレンス]
 http://www.cppreference.com/ (英語)
 http://www.cppll.jp/cppreference/ (↑の日本語訳だけど最新は反映しない)
[禿 Stroustrup]
 http://public.research.att.com/~bs/
[C++ International Standard]
 http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=38110
[JTC1/SC22/WG21 - C++]
 http://www.open-std.org/jtc1/sc22/wg21/
  ここから規格の最新(2003より新しい)ドラフトがダウンロードできる。
[JIS X3014]
 http://www.jisc.go.jp/app/pager?&RKKNP_vJISJISNO=X3014
  ISO規格の日本語訳。JIS X 3014:2003はISO/IEC 14882:2003 (E)に対応。
3デフォルトの名無しさん:2008/07/26(土) 02:52:11
4デフォルトの名無しさん:2008/07/26(土) 02:52:35
5デフォルトの名無しさん:2008/07/26(土) 02:52:59
STLつかうと一気に実行ファイルサイズが10倍に?!

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

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

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

#include <stdafx.h>
後死ね。

言葉が悪いな。それで教えているつもりか。
まぁヒントぐらいにはなったな。
うむごくろう。
6デフォルトの名無しさん:2008/07/26(土) 04:52:27
7デフォルトの名無しさん:2008/07/26(土) 05:59:45
まぁ新スレぐらいにはなったな。
うむごくろう。
8デフォルトの名無しさん:2008/07/26(土) 06:32:26
大域識別子の宣言・定義について教えてください。
通常、
extern int i;
のようにすると、それは宣言と見なされてインスタンスは作成されませんよね。
ところが
extern int i = 1;
のように書くと、インスタンスが作成され1で初期化されます。
ということで、externが付いても初期化がされているものは、externが
無視されるのだろうと、かってに自分を納得させていました。ところが
int i;
extern int i = 1;
という定義の重複と思われるコードをコンパイルしてみると、エラーは出ず
実行したらiが1で初期化されていました。はて?と思い、今度は前後を変えて
extern int i = 1;
int i;
でコンパイルしてみると、iの再定義ということでコンパイルエラーになりました。
これらの現象から帰納すると、どういうことになるんでしょうか。
単にコンパイラがおかしいのでしょうか。ちなみにVC++ 2008 Expressです。
9デフォルトの名無しさん:2008/07/26(土) 07:50:16
>>4
>  Apache STDCXX http://incubator.apache.org/stdcxx/
301 Moved Permanently になってた。
次スレで↓に入れ替えおねがい。
Apache C++ Standard Library (STDCXX) http://stdcxx.apache.org/
10デフォルトの名無しさん:2008/07/26(土) 08:14:28
>>8
C だと int i; が仮定義 (tentative definition) とかいう扱いになって、
コンパイル〜リンクできるはず。

C++ だと、 extern が付いてない int i; も、初期化子が付いてる extern int i = 1; も
両方とも(仮ではない)定義とみなされる(規格の 3.1 Declarations and definitions p2 )ので、
定義が重複していることになり、 ODR 違反で未定義動作になる。(規格の 3.2 One definition rule )

g++ 3.4.4 では、並べて書くと redefinition of `int i' というエラーになった。別々の
ファイルに分けて書けばリンクエラーになると思う。 VC は、 C と同じ動作になってる
・・・と思ったけど順番変えてエラーになるのは意味が分からんな。

まぁ未定義動作なんてこんなもんだろ。
11デフォルトの名無しさん:2008/07/26(土) 08:53:02
>>10
ありがとうございます。
なんかコンパイラのクセみたいな感じですかね。
そんなことで悩むのはこれまでとします。
12デフォルトの名無しさん:2008/07/26(土) 11:45:29
v(^・^)v
13デフォルトの名無しさん:2008/07/26(土) 12:47:58
入力した値が偶数か奇数か調べるプログラムを作りたいのですが 偶数(2n)と奇数(2n-1)の部分の表現の仕方がわかりません。
#include <iostream>
using namespace std;
int main() 
{
int num;
int sum = num

cout << "整数を入力してください\n";

cin >> num;

if (num == 偶数) {
cout << "偶数です\n";
}

else if (num == 奇数) {
cout << "奇数です\n";
}

return 0;
}
14デフォルトの名無しさん:2008/07/26(土) 12:50:24
>>13
num % 2 == 0
num % 2 == 1
15デフォルトの名無しさん:2008/07/26(土) 12:50:29
>>13
剰余でぐぐれ
16デフォルトの名無しさん:2008/07/26(土) 12:50:59
>>14 15

ありがとうございます
17デフォルトの名無しさん:2008/07/26(土) 12:51:02
>>13
2で割り切れたら偶数、割り切れなかったら奇数だ。
18デフォルトの名無しさん:2008/07/26(土) 12:51:39
やはりプログラムは応用力ですね・・・・。
修行に出てきます。
19デフォルトの名無しさん:2008/07/26(土) 12:56:03
if( num & 1)
奇数
else
 偶数
情報処理の基礎的にはこっちじゃない?
20デフォルトの名無しさん:2008/07/26(土) 12:58:44
>>19 ビット単位の論理演算子ですか?

自分はこういう風にコードを書いてみました。
#include <iostream>
using namespace std;

int main()
{
int num;

cout << "整数を入力してください\n";

cin >> num;

if (num % 2 == 0) {
cout << "偶数です\n";
}

if (num % 2 != 0) {
cout << "奇数です\n";
}

return 0;
}
21デフォルトの名無しさん:2008/07/26(土) 13:12:58
num % 2 == 0が偽だった場合は奇数確定なんだから、num % 2 != 0は不要だろ。
22デフォルトの名無しさん:2008/07/26(土) 13:16:32
>>21 大変申し訳ございません 修正しました
if {cout << "奇数です\n";}
23デフォルトの名無しさん:2008/07/26(土) 13:19:42
本当にコンパイルと実行して試してるの?
24デフォルトの名無しさん:2008/07/26(土) 13:43:04
>>23
はい、試みてます。
25デフォルトの名無しさん:2008/07/26(土) 13:43:48
>>22訂正

else {cout << "奇数です\n";}

連投すいません;;
26デフォルトの名無しさん:2008/07/26(土) 13:44:46
これからドリトル先生の祝賀会に行くので落ちます。

お疲れ様でした
27デフォルトの名無しさん:2008/07/26(土) 13:47:03
ちゃんと理解できていれば応用もへったくれもないだろ。
定義に遡って定義どおりに書くだけだ。
cout << (num % 2 == 0) ? "偶数" : "奇数";

ビット演算を持ち出す必要は全くないな。
28デフォルトの名無しさん:2008/07/26(土) 13:48:56
ビット演算の方が速いじゃない
29デフォルトの名無しさん:2008/07/26(土) 13:54:06
いまどきビット演算にこだわるおとこの人って…(笑)
30デフォルトの名無しさん:2008/07/26(土) 13:56:35
>>28
最適化ありでアセンブラ見比べてみ。
31デフォルトの名無しさん:2008/07/26(土) 13:57:10
条件演算子を持ち出す必要も全く無いけどな。
32デフォルトの名無しさん:2008/07/26(土) 13:58:41
どうせ "num % 2" の演算は最適化されるだろうから
わざわざビット演算で書いてわかりにくくする必要はない

本当に "num % 2" が割り算を発生させていて、
かつその部分のコードが実行速度のボトルネックになってない限り
ビット演算を使う必要はないんじゃないの
(premature optimization ってやつだ)
33デフォルトの名無しさん:2008/07/26(土) 14:08:42
おれはビット演算が当たり前になってるからMod演算は逆に読みにくいし
if( num % 2 )
だけならともかく”==0”が付くことで式が増えて解釈が二度手間になる。
34デフォルトの名無しさん:2008/07/26(土) 14:12:10
>>33

if ( num % 2 )
{ /*奇数*/ }
else
{ /*偶数*/ }
35デフォルトの名無しさん:2008/07/26(土) 14:35:22
ビット演算が当たり前になってる奴のコードって読みづらい
36デフォルトの名無しさん:2008/07/26(土) 14:36:58
そんな低脳ぶりをアピールされても困る
37デフォルトの名無しさん:2008/07/26(土) 14:46:02
僕が質問したばかりに言い争いが始まってしまって申し訳ない。

反省と言っては何ですが、30分間冷房を28度にします。常時19度・風速急
38デフォルトの名無しさん:2008/07/26(土) 14:48:36
切れよw
39デフォルトの名無しさん:2008/07/26(土) 17:43:36
えるしっているか びっとえんざんは かんきょうの えいきょうを うけやすい
40デフォルトの名無しさん:2008/07/26(土) 17:46:54
c++の課題でgets()を使い文字列を取得、Ctlr+Zが入力されたら処理を中断するというものが出たのですが、Ctrl+zの入力で難航しています。
gets()はEOFが入ったらnull文字に置き換えるのですよね?

char strBuff[256];

printf("文字を入力して下さい。(Ctrl+Zで終了)\n");
gets(strBuff);

if(strBuff[0] != '\n'){
printf("%s\n", strBuff);
}else{
printf("Ctrl+Zが認識されました。\n");
}

これを実行するとCtrl+Zを押しても認識してくれないのですが、どのような判定式にすればいいのでしょうか
41デフォルトの名無しさん:2008/07/26(土) 17:51:28
getsでEOF判定するの?
ほんとに問題文にそう書いてあんのか?
42デフォルトの名無しさん:2008/07/26(土) 17:53:28
>>41
問題文には、
○入力は、gets関数を使うこと
○CTRL+Zで入力を終了し、処理をすること
とありました。

もしかしてgetsではCTRL+Zを判別することは出来ないのですか?
43デフォルトの名無しさん:2008/07/26(土) 18:02:34
name>vi t.c
#include <stdio.h>

int main(void){
 char c[256];
 printf(">");
 gets(c);
 //fgets(c,256,stdin);
 printf("%s",c);
 return 0;
}

name>gcc t.c
/tmp/cc4hr3hR.o: In function `main':
t.c:(.text+0x1d): warning: the `gets' function is dangerous and should not be used.
name>./a.out
>(ctrl+z)
中断
name>fg
./a.out
a
a
name>

c++じゃないけど。
ctrl+zの制御って、結構深いところまで潜らないと奪えなかったりしないのかなぁ、知らない。
44デフォルトの名無しさん:2008/07/26(土) 18:03:44
>>42
これで一応いいんじゃないかな
gets()でCtrl+Zはもとの文字列に何もしないということなので、

int main()
{
char strBuff[256] = "";

printf("文字を入力して下さい。(Ctrl+Zで終了)\n");

gets(strBuff);
if(strBuff[0] != '\n' && strBuff[0] != '\0' ){
printf("%s\n", strBuff);
}else{
printf("Ctrl+Zが認識されました。\n");
}
return 0;
}
45デフォルトの名無しさん:2008/07/26(土) 18:21:25
そもそもgets()を使わせる時点で唾棄すべき課題だ。
おまけにCtrlZなんて環境依存な入力を要求する辺り、出題者の非学非才が窺える。
46デフォルトの名無しさん:2008/07/26(土) 18:22:09
>>43,44
ありがとうございます、なんとか出来そうです。
もとの文字列に手を加えないのですね。そして初期化してなかったから出来なかったと・・・
47デフォルトの名無しさん:2008/07/26(土) 18:26:33
>>45
まぁ初心者だったころの気持ちを忘れてるんだろうね
学ばせる順番からいったら最初はgetsがでてきても不思議ではない
おまじないとしてfgetsを使うように言えと?w
48デフォルトの名無しさん:2008/07/26(土) 18:30:19
そもそも、C++で、だぞ。
49デフォルトの名無しさん:2008/07/26(土) 18:31:54
はいはいお前らここはC++相談室ですよ
50デフォルトの名無しさん:2008/07/26(土) 22:11:09
安全なgetsを作ればいいんですねわかります。
template<std::size_t n>
inline char* gets(char (&buf)[n])
{
&nbsp; return fgets(buf, n, stdin);
}
ここまで書いてMSDNライブラリ見たら、
VC++には本当にこういうプロトタイプのgetsがあるらしいと知った。

>>40-44
getsもfgetsもEOF入れたら戻り値はヌルだから、それで判定すればいい。
51デフォルトの名無しさん:2008/07/26(土) 22:13:37
Safe CRT標準入りしてくれないかなー
52デフォルトの名無しさん:2008/07/26(土) 22:21:56
一生しねーよwww
53デフォルトの名無しさん:2008/07/26(土) 23:33:16
すみません、このスレの人たちはVBは使えるのですか?
54デフォルトの名無しさん:2008/07/26(土) 23:38:37
使わない
55デフォルトの名無しさん:2008/07/26(土) 23:54:35
×使わない
○使えない
56デフォルトの名無しさん:2008/07/27(日) 00:07:22
VB厨見たの数年ぶりだ
57デフォルトの名無しさん:2008/07/27(日) 00:14:05
すみません、このスレの人たちはRubyは使えるのですか?
58デフォルトの名無しさん:2008/07/27(日) 00:16:23
それはC++に関係のあることか?
59デフォルトの名無しさん:2008/07/27(日) 00:17:43
すみません、関係なかったです。もう書きません
60デフォルトの名無しさん:2008/07/27(日) 00:18:49
<p>
6160:2008/07/27(日) 00:19:50
HTMLのruby要素だとボケかまそうとしたら途中で書き込んでしまった。
もう寝る。
62デフォルトの名無しさん:2008/07/27(日) 02:07:11
キモイ
63デフォルトの名無しさん:2008/07/27(日) 06:17:44
auto_ptrの実装の例を読んだのですが、auto_ptr_ref型みたいな補助型が
あって、それと言語仕様の微妙なからくりを使って、なにやらを実現してる
ようですが、結局constなauto_ptrオブジェクトの所有権を変更できないように
するためのものなんでしょうか?
このからくりを説明できる物好きで暇な人いますか?
64デフォルトの名無しさん:2008/07/27(日) 07:22:58
>>63
auto_ptrを関数の戻り地の型にしたいだろ?
でも関数の戻り値はrvalueだから、普通にauto_ptrを実装したのでは、所有権を移せない。
かといって、コンストラクタでconstなauto_ptrをコピーするようにした場合、auto_ptrの意味がなくなってしまう。
どうにかならんかってんで、「言語仕様の微妙なからくり」を使っているわけだ。

Move Semanticsがあらまほしけれ。
65デフォルトの名無しさん:2008/07/27(日) 11:46:07
>>63
auto_ptr(auto_ptr<T>& o)のコンストラクタに
一時オブジェクト(戻り値)を渡せないため。

渡せない理由は多分このへん。
http://q.hatena.ne.jp/1167111891
6663:2008/07/27(日) 12:50:45
レスどうもです。auto_ptrを普通に実装したのではまずいということはわかりました。
どうやって問題を解決しているのか、そのからくりを誰か語り倒してもらえませんか。
6763:2008/07/27(日) 12:52:59
今から実装の例を書き込みます。
6863:2008/07/27(日) 13:05:23
この機構は、コピーコンストラクタとコピー代入演算子に適用されているようですが
話をコピーコンストラクタに集中するとします。たいていはstd名前空間に次のように
定義されているようです。

template<class Y> struct auto_ptr_ref{
 Y* yp;
 auto_ptr_ref(Y* rhs):yp(rhs){}
};

template<class T> class auto_ptr{
 T* ap;
public:
 //コンストラクタ
 auto_ptr(auto_ptr& rhs):ap(rhs.release()){}
 auto_ptr(auto_ptr_ref<T> rhs):ap(rhs.yp){}
 //型変換演算子
 template<class Y> operator auto_ptr_ref<Y>(){
  return auto_ptr_ref<Y>(release());
 }
 template<class Y> operator auto_ptr<Y>(){
  return auto_ptr<Y>(release());
 }
 //...他メンバ省略
};

こんな感じのようです。型変換演算子も駆使してるようですが、わけわかめです。
6963:2008/07/27(日) 13:22:43
あれ・・・なんかわかってきたようなw
7063:2008/07/27(日) 13:38:12
auto_ptr<T>型のコンストラクタに右辺値が渡された場合……

1.auto_ptr(auto_ptr_ref<T> rhs)がコールされ
2.operator auto_ptr_ref<T>()により、実引数の右辺値であるauto_ptr<T>オブジェクトが
 動的資源の所有権を失い、変わりにその動的資源へのポインタを持った
 auto_ptr_ref<T>型に変換され1.の仮引数となる
3.仮引数のauto_ptr_ref<T>オブジェクトがメンバとしてもってるポインタypで
 *thisオブジェクトのメンバapを初期化

こんな感じかな?
71デフォルトの名無しさん:2008/07/27(日) 13:39:26
直接ポインタにすると色々問題が起きる事があるから
クラス挟んでるだけじゃない?
72デフォルトの名無しさん:2008/07/27(日) 13:54:05
explicit が抜けてるぞ。
これがないと全く無意味になる。
7363:2008/07/27(日) 13:56:24
explicitが必要なのは、生ポインタを受け取るコンストラクタでは?
74デフォルトの名無しさん:2008/07/27(日) 13:57:31
g++ には auto_ptr_ref のコンストラクタに explicit がついてるぜ
7563:2008/07/27(日) 14:00:12
auto_ptr_ref型は、ユーザーが直接扱うことは想定してないので
explicit付けても付けなくてもどっちでもいいやって感じ?
76デフォルトの名無しさん:2008/07/27(日) 17:07:09
explicit無くても大丈夫だよ。
77デフォルトの名無しさん:2008/07/27(日) 17:08:58
テキストファイルを読み込んで、std::stringに格納する効率良い方法はないですか?

ifstreamでファイルを開いて、read関数でchar*型のバッファにコピーして、
char*型のバッファをstringのコンストラクタに渡す方法でとりあえず書きましたが、
ifstream→char*型のバッファ→stringと2回コピーが発生して効率悪そうです。
78デフォルトの名無しさん:2008/07/27(日) 17:12:40
>>77
std::ifstream ifs;
std::string str;
getline(ifs, str);
79デフォルトの名無しさん:2008/07/27(日) 17:20:02
C++相談室 part60 http://www.bookshelf.jp/2ch/tech/1200044614.html
C++相談室 part61 http://www.bookshelf.jp/2ch/tech/1205059063.html

にauto_ptr_refの話や、part60の487-489のような
auto_ptr_refの仕組みを利用したMove Semantics的な実装の話が出てる
80デフォルトの名無しさん:2008/07/27(日) 17:23:16
>>78
thx
81デフォルトの名無しさん:2008/07/27(日) 18:03:09
>>78
全ての行に対して何かの処理f()をするとき
while (1) {
getline(ifs, str);
if (ifs.eof() || !ifs()) break;
f(str);
};
と書いてたんだが、もっといい書き方ってない?
(for_eachとか iterator使うのとは別の観点で)

if文を真ん中に入れてbreakするのがどうもダサく見えてしまう
eof以外にエラー判定もしておかないと、無限ループになることがある

あと、改行の無い巨大ファイルを読んだときは、
std::bad_allocが投げられるのかな?
その場合 try catch で囲っておけば、抜けた後 strのメモリは開放されて、
普通に処理を続行できる?
例えば、「ファイルが不正です」と表示してメインループに戻るとか
82デフォルトの名無しさん:2008/07/27(日) 18:07:33
while (getline(ifs,line)) {
ほげほげ
}
83デフォルトの名無しさん:2008/07/27(日) 22:44:53
サンクスコ

ちなみに、改行なし巨大ファイルを読んだら例外出さずに抜けました
84デフォルトの名無しさん:2008/07/27(日) 23:46:32
例外が欲しければ、予めifs.exceptions()で指定しておけばいいはず。
85デフォルトの名無しさん:2008/07/28(月) 00:55:49
auto_ptr_refの話題からの派生だけど
VC++コンパイラは、非const参照型で一時オブジェクト受け取れちゃうんだね。
VC++ってウンコ?とも思ったけど、C++0xでも受け取れるようになるとかって
本当なのかね?
参照で受け取っても、一時オブジェクトだけに、すぐ消えちゃうんじゃないのかな。
86デフォルトの名無しさん:2008/07/28(月) 01:10:26
>>85
「プロジェクト」→「〜のプロパティ」→「構成プロパティ」
→「C/C++」→「言語」→「言語拡張を無効にする」
87デフォルトの名無しさん:2008/07/28(月) 01:11:07
たしか右辺値参照とかいうやつだっけ>C++0x
新しい構文になるみたいだから従来の参照と混同はせんだろう
特別使いたい場合にだけ注意して使うようにしてればいいんじゃないか
88デフォルトの名無しさん:2008/07/28(月) 01:48:00
そうか…言語拡張機能だったのか。拡張ってまぎらわしいね。
標準がいいよ。
89デフォルトの名無しさん:2008/07/28(月) 12:10:56
警告出るだろ?
90デフォルトの名無しさん:2008/07/28(月) 12:34:29
警告も最高レベル(W4)に変更しないと出なかったりする。
91デフォルトの名無しさん:2008/07/28(月) 18:35:43
C/C++やVBは、レベル低い
http://pc11.2ch.net/test/read.cgi/prog/1217229421/
92デフォルトの名無しさん:2008/07/29(火) 01:40:00
このコードの※のところがエラーになるのですがなぜでしょうか?
テンプレートコピーコンストラクタなるものを試してみたのですが。
コンパイラは「コンパイルされたクラスの テンプレート のインスタンス化
       'C<T>::C<int>(const C<int> &)' の参照を確認してください」
と言ってきます。

template<class T>
class C{
T m;
public:
C(T _m = T()):m(_m){}
template<class Otr>
    C(const C<Otr> &c){ m = c.m; }
};

int main()
{
C<int> Ci;
C<double> Cd(Ci);   // ……※
}
93デフォルトの名無しさん:2008/07/29(火) 02:04:02
>>92
コンパイラ何?

gcc 3.4 だとこうなる。
> : In constructor `C<T>::C(const C<Otr>&) [with Otr = int, T = double]':
> :13: instantiated from here
> :3: error: `int C<int>::m' is private
> :7: error: within this context
んで m を public にしたら通る。
94デフォルトの名無しさん:2008/07/29(火) 02:13:23
レスありがとうございます。

コンパイラはVC++2008です。
確かにmがパブリックなら通りますね。
もしかして、テンプレートメンバ関数って、privateなメンバにアクセスできない
ということですかね…なんじゃそら
95デフォルトの名無しさん:2008/07/29(火) 02:14:23
C<int>とC<double>は別のクラス
96デフォルトの名無しさん:2008/07/29(火) 02:17:12
あ、当然ですね、そういえば。
C<int>とC<double>はまったく別の型だから、privateなメンバを相互参照
できませんね!
97デフォルトの名無しさん:2008/07/29(火) 02:17:35
>>92
エラーメッセージそれだけじゃないだろ。
98デフォルトの名無しさん:2008/07/29(火) 02:23:04
スクロールしたら上の方にありました^^;まだ慣れて無くて
99デフォルトの名無しさん:2008/07/29(火) 15:09:44
質問です
環境はVC 6.0 、OS : Xp  です
メンバ関数ポインタについてですが(ソースコードは次のレスで書きます)
main関数内のメンバ関数ポインタ(CSample::*pFunc)から呼び出す(@)
メンバ関数(CSample::func1)から、メンバ変数であるメンバ関数ポインタ(CSample::*mpFunc)を使って呼び出す(A)
はできるのですが、
main関数内で、メンバ関数ポインタ(CSample::*mpFunc)を使って呼び出す(B)
がいろいろ試してみましたができません
そういうことはできないのでしょうか
100>>99:2008/07/29(火) 15:10:51
#include <iostream>
using namespace std;

class CSample
{
public:
void func(){cout << "CSample::func()" << endl;};
void (CSample::*mpFunc)();
CSample(){mpFunc = func;};
void func1(){(this->*mpFunc)();}
};


int main()
{
void (CSample::*pFunc)() = &CSample::func;

CSample obj;
(obj.*pFunc)(); // @

obj.func1(); // A

(obj.*mpFunc)(); // B

return 0;
}
101デフォルトの名無しさん:2008/07/29(火) 17:55:24
すみません、素朴な疑問なのですが
ostringstreamというのは関数の戻り値には指定できないのでしょうか?

ostringstream function();

こういったシグニチャのメソッドを作成したかったのですが、
どうも出来ないようで…。
不可能であるなら、その理由も教えて頂けると助かります。

よろしくお願いします。
102デフォルトの名無しさん:2008/07/29(火) 17:56:57
class X{
int m;
};
とあった場合、
&X::mと&(X::m)は同じ意味?それとも別の意味?それともどちらかは無意味?
103デフォルトの名無しさん:2008/07/29(火) 18:07:22
どちらもエラー
104デフォルトの名無しさん:2008/07/29(火) 18:08:02
>>102
::名前空間を解決することしかしないので、前者と後者は同じ意味になる。
括弧をつけることに意味を見出せないとすれば、後者は無意味。
105デフォルトの名無しさん:2008/07/29(火) 18:16:48
>>101
ostringstreamはコピーできないのでエラーになる。
とりあえずはnewしてポインタでも返すようにすればいい。

ちなみに、将来的には中身を移し替える手法で戻り値にできるようになる。
C++0xに乞う御期待。
106デフォルトの名無しさん:2008/07/29(火) 18:28:18
>>101
#include <memory>
stdd::auto_ptr<ostringstream> function(); にしなさい。
107デフォルトの名無しさん:2008/07/29(火) 18:30:01
× stdd::
○ std::
108デフォルトの名無しさん:2008/07/29(火) 18:31:31
>>104
ありがとうございます。
109デフォルトの名無しさん:2008/07/29(火) 21:11:01
>>99
(obj.*obj.mpFunc)();
110デフォルトの名無しさん:2008/07/29(火) 21:54:24
>>109
99じゃないけどやっぱりobj2個いるのか。
111デフォルトの名無しさん:2008/07/29(火) 22:27:52
いるよ
112デフォルトの名無しさん:2008/07/29(火) 22:51:03
まずメンバ関数ポインタを取得するのに一個。
次にそのポインタをインスタンスにマッチングするのにもう一個。
113>>99:2008/07/29(火) 22:51:32
>>109
ありがとうございます
助かりました
できれば理屈も教えていただけるとありがたいのですが、一応
114>>113:2008/07/29(火) 22:52:33
>>112
ニアミスでした
ありがとうございました
115デフォルトの名無しさん:2008/07/29(火) 23:40:01
CSample(){mpFunc = func;}; ←ここでもエラー出るんですが
116デフォルトの名無しさん:2008/07/29(火) 23:47:13
多分後ろのセミコロン取るんでしょう
何故かVC6ではエラー出なかった
117デフォルトの名無しさん:2008/07/30(水) 00:31:20
セミコロン取ってもエラーが出ます
コンパイラはBCC5.9.3です
エラーは

エラー E2235 member1.cpp 21: メンバー関数は呼び出すかそのアドレスをとらなければならない(関数 CSample::CSample() )

と出ます
118デフォルトの名無しさん:2008/07/30(水) 00:57:58
CSample(){mpFunc = &CSample::func;}
119デフォルトの名無しさん:2008/07/30(水) 01:32:05
>>118
d
120デフォルトの名無しさん:2008/07/30(水) 23:04:01
こんなの見つけた。

あなたはC++の発明者? それとも創造者?〜Bjarne Stroustrup氏との対話〜
http://codezine.jp/a/article/aid/2834.aspx
121デフォルトの名無しさん:2008/07/30(水) 23:20:14
とりあえず、びよよんの禿っぷりは一流だと思った
122デフォルトの名無しさん:2008/07/31(木) 01:37:12
×一流
○超一流
123デフォルトの名無しさん:2008/07/31(木) 01:38:35
禿、プログラミング言語C++第4版の執筆作業に戻るんだ!
124デフォルトの名無しさん:2008/07/31(木) 01:58:19
>>123
その前にまずC++0xが決まらんと
125デフォルトの名無しさん:2008/07/31(木) 12:37:58
その前にヒゲを伸ばしてくれ
126デフォルトの名無しさん:2008/07/31(木) 13:14:46
>>120
コメントにもあるけど、引用された英文の邦訳が筆者の認識混じりの意訳になってるな。
あやうく見落とすところだった。
元の英文は、メールでのやりとりなのかな?
127デフォルトの名無しさん:2008/08/01(金) 14:34:01
>>2のISO規格の日本語訳を見ようと思ったのですが、リンク先がnot foundになっていたので、
トップページからX3014を検索して開いたのですが、「ダウンロードしての閲覧は禁止されています。」というエラーが出て見ることができません。
どうすれば見れますか?
128デフォルトの名無しさん:2008/08/01(金) 14:37:52
ダウンロードしての閲覧は禁止されています。
129デフォルトの名無しさん:2008/08/01(金) 14:58:07
>>128
リンクを左クリックしただけです。
ダウンロードしないで閲覧する方法がわかりません。
130デフォルトの名無しさん:2008/08/01(金) 15:03:29
>>129
http://www.jisc.go.jp/app/pager?id=62935
これならどうよ。
トップページから検索したら行き着いたぜ。
131デフォルトの名無しさん:2008/08/01(金) 15:06:40
>>130
ファイルが見つかりません。
File not found.

って出ます。
132デフォルトの名無しさん:2008/08/01(金) 15:10:53
っ Adobe Reader をインストール
133デフォルトの名無しさん:2008/08/01(金) 15:19:49
>>131
直接アクセス禁止か、クッキーか何かによる制限をしてるのかもしれない。
一度、トップページへ行って検索してみては?
134デフォルトの名無しさん:2008/08/01(金) 15:22:47
>>132の言う通り、
Adobe Readerのバージョンが古くて読み込めないのかもしれないね。
135デフォルトの名無しさん:2008/08/01(金) 15:26:10
>>132-134
インストールしたら見れるようになりました。
バージョンが古かったのかもしれません。
お騒がせしましたorz
136デフォルトの名無しさん:2008/08/01(金) 22:21:49
逆に、Adobe ReaderなどPDFビューアの類が全くインストールされていない状況だと、
ダウンロードのダイアログが出てうわ何をするくぁswdfgh
137デフォルトの名無しさん:2008/08/02(土) 09:17:19
||つ[IEキャッシュ]

||≡3
138デフォルトの名無しさん:2008/08/02(土) 15:04:59
C++では、大域のconstオブジェクトにstatic付けても意味ないよね?
つまり、staticつけなくても外部リンケージはもともと持ってないってことでOK?
139デフォルトの名無しさん:2008/08/02(土) 15:12:59
ん?
staticがついてなきゃ外部から参照できるんじゃね?
140デフォルトの名無しさん:2008/08/02(土) 15:57:27
>>139
名前空間スコープで const 付きのオブジェクトはデフォルトで内部リンケージ。
これは C++ と C との違いのひとつ。
141デフォルトの名無しさん:2008/08/02(土) 16:06:56
名前空間スコープって、グローバルスコープも含まれるの?
142デフォルトの名無しさん:2008/08/02(土) 16:20:38
やってみれ
143デフォルトの名無しさん:2008/08/02(土) 16:37:54
いや、一般的な話でさ。
グローバルスコープも何らかの名前空間の1つとして分類されるのかなと。
でも無名名前空間もあるし、どういう位置づけなんだろ。
144デフォルトの名無しさん:2008/08/02(土) 17:07:35
>>143
「グローバル名前空間」ってことになってる。

3.3.5p6 より
"The outermost declarative region of a translation unit is also a namespace, called the global namespace.
A name declared in the global namespace has global namespace scope (also called global scope)."
145デフォルトの名無しさん:2008/08/02(土) 17:15:47
>>138>>140
しらんかった。勉強になった。
知らなくても困らんけどw
146デフォルトの名無しさん:2008/08/02(土) 17:21:10
知らんとODR違反とかで困らないか?
147デフォルトの名無しさん:2008/08/02(土) 17:26:28
std::vector< int > vint;
vint.push_back( 1 );
int *p = vint[0]; //1のアドレス
vint.push_back( 2 );
vint.push_back( 3 );
・・・
とvintに追加していったとき、pのアドレスは正しいアドレスを保持
できるんでしょうか? 出来なさそうではあるけど・・
148デフォルトの名無しさん:2008/08/02(土) 17:29:07
>出来なさそう
正解
149デフォルトの名無しさん:2008/08/02(土) 18:00:48
>>144
おお、サンクス
150デフォルトの名無しさん:2008/08/02(土) 18:01:20
>>147
reserveしとけば? 推奨はしないけど。
151デフォルトの名無しさん:2008/08/02(土) 18:11:19
>>146
グローバルのconstオブジェクトが外部リンケージ持たないのと
ODR違反ってどう関係あるんだ?
152147:2008/08/02(土) 18:28:26
>>148>>150
やっぱり確実じゃないですよね。
規則性のないバグになるのは困るのでやめときます。
153デフォルトの名無しさん:2008/08/02(土) 18:37:59
>>152
正解。
154デフォルトの名無しさん:2008/08/02(土) 18:42:17
誰もつっこんでないが
>int *p = vint[0]; //1のアドレス
これ、アドレスじゃなくて、要素の値を代入しちゃってる
155デフォルトの名無しさん:2008/08/02(土) 18:58:26
たんなるタイプミスだろそれは。
問題はそこじゃねーよ。
156デフォルトの名無しさん:2008/08/02(土) 19:09:55
          __、
     ,r´⌒ヽ,⌒ヽ,ヽ
   (⌒)、   .人  λ\、 ._____
    \. \    、 ヽ./ ー  ー\
     |\ \    ヽ./ ( ●) ( ●)
     |  \  \ /     (__人__) \  はい、どーもすみませんでした
     |.   \   |       ` ⌒´   |
  .   |.   |.\_ノ\            /
  .   |.   |   |   \______/
  .   |   )  .|     . . ̄ ̄
  .   |   |  .|
     |   |.|  .|
  .   |  | .| .|
     /  / / ヽ,
    (__ノ  ヽ、__つ
157デフォルトの名無しさん:2008/08/03(日) 10:27:47
>>152
「確実じゃない」というのがどの範囲まで指した言葉なのかによりますけれど,
コンテナ内への参照が無効化されるのを reserve で阻止するのは
きちんと扱うならば規格の保証の範囲内ですよ
158デフォルトの名無しさん:2008/08/03(日) 12:50:22
STLのstringについて質問です

void main()
{
  _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF);
  std::string str("tekito");
  str.append("namojiretu");
  exit(-1);
}

上記のコードがメモリリークになるのですが、どうやって解決すればいいのでしょうか?
eraseやclearを使っても解決できません。
また条件が特定できなかったので明記しませんが、使う場所によっては文字列中に改行文字があったときだけ
メモリリークするような現象も起こりました。
解説よろしくお願いします
159デフォルトの名無しさん:2008/08/03(日) 12:57:23
C++ではexitを使わないこと。
160デフォルトの名無しさん:2008/08/03(日) 13:08:51
>>158
こんなんとか。
http://msdn.microsoft.com/ja-jp/library/8bsz08tx.aspx

_CRTDBG_MAP_ALLOC 定義した状態の出力を見れば、もう少し情報が増えるかもね。
161デフォルトの名無しさん:2008/08/03(日) 13:09:20
んじゃあ何で終了するんですか?
162デフォルトの名無しさん:2008/08/03(日) 13:11:31
mainから素直に抜けて下さい。
むしろ、int mainにしてreturnして下さい。
163デフォルトの名無しさん:2008/08/03(日) 13:12:24
exit(-1)の中でプログラムが終了・リークチェックが走る
strはスコープを抜けてないのでデストラクタが走らない。
164デフォルトの名無しさん:2008/08/03(日) 13:14:03
>>160
>Visual Studio .NET 以前のバージョンの標準テンプレート ライブラリは _CrtDumpMemoryLeaks が誤検出を報告する原因となっていましたが、最新リリースでは修正されています。
これ今現在は大丈夫ということなんじゃないんですか?
ちなみに使っているのはVS2005です。
165デフォルトの名無しさん:2008/08/03(日) 13:17:40
>>162
>>163

そうするしかないのかー
サブ関数とかで階層が深くなってるとmainまで戻してくのが面倒だったのでexit使ってたんですが…
うーん、直すしかないのか
166デフォルトの名無しさん:2008/08/03(日) 13:27:49
プログラム終了用の例外作って代わりにすればよくね?
main関数でcatchすること前提にすればギリギリ有りな気が。

struct exit_class{};
void exit_cpp(){
throw exit_class();
}

167デフォルトの名無しさん:2008/08/03(日) 13:30:48
>>166
すんません、アホでした
例外投げるという方法をすっかり忘れていました
ありがとうございました
168デフォルトの名無しさん:2008/08/03(日) 15:18:40
俺は何の躊躇もなくexit使ってるぜ。
組込みじゃないんだから、プログラム終了時のメモリリークなんてOSがなんとかしてくれるさー
169デフォルトの名無しさん:2008/08/03(日) 15:21:07
それでもリソースリークのリスクは依然としてある。
170デフォルトの名無しさん:2008/08/03(日) 15:44:26
そのexitがエラー時の終了じゃなく、通常の終了処理なら
それはプログラミングの怠慢だろ
スパゲティ風味がするぞ
171デフォルトの名無しさん:2008/08/03(日) 16:30:16
今さら人には聞けないシリーズなんですが、vectorとdequeってどう発音してますか?
vector:ベクトル?ベクタ?
deque:デック?ディーク?デキュー?
172デフォルトの名無しさん:2008/08/03(日) 16:33:45
>>170
俺のスパゲティはおいしいんだい!
リソース解放はatexit()で解放ルーチン登録してるからいいもん!


>>171
ベクターとデキューって心の中で発音してます。
173デフォルトの名無しさん:2008/08/03(日) 16:37:38
>>171
俺はデキューと読んでいるが、確かデックが正しい発音のハズ。
174ひみつの検閲さん:2024/06/28(金) 14:26:49 ID:MarkedRes
このレスは権利侵害の申し立てや違法もしくはその疑いにて不可視または削除されました。
削除日時:2013-11-17 08:06:43
https://mimizun.com/delete.html
175デフォルトの名無しさん:2008/08/03(日) 17:47:53
>>174
それもう飽きた。

>>172
exit()を使いたいがために登録し捲くるの?
個数制限もあるのに?
176デフォルトの名無しさん:2008/08/03(日) 18:21:38
int main try{
}
catch(...){
}

これ最強じゃね?
177デフォルトの名無しさん:2008/08/03(日) 18:45:18
>>174
弓月さん!!コピペなら俺も協力させてもらいますよ!!!









【自作自演】弓月城太郎氏に関するまとめ【神秘体験】
http://d.hatena.ne.jp/yaneurao/20080619
178デフォルトの名無しさん:2008/08/03(日) 19:12:04
実際、メモリーリークなんてプログラムが終了すれば、全部解放されるんでしょ?
Windowsなら。
179デフォルトの名無しさん:2008/08/03(日) 19:15:25
終了時に解放しないのは、低レベルなリソースだけでみれば、Windowsでは問題ないが、

しかしデストラクタが走らないので、
例えばデストラクタでファイルへの書き込みを行うだとか、
そういうことをしているとまずい。
180デフォルトの名無しさん:2008/08/03(日) 19:40:52
Windowsは、プログラム終了時に入出力チャンネルのクローズも
やってくれんでしょ?
181デフォルトの名無しさん:2008/08/03(日) 19:49:38
class hoge{
……
void write_all_data(void);
void clear_all_resources(void);
~hoge(void);
}

hoge::~hoge(void){
write_all_data();
clear_all_resources();
}

こういう形だとまずいってことじゃないの?
182デフォルトの名無しさん:2008/08/03(日) 19:50:40
>>175
まあ俺がそんなにファイルとか扱うプログラムを書かないだけだったりするけどな。

>>180
>>179が言っているように、デストラクタ内でログの書きだしとか、ロックファイルの削除とか、
そういった処理を行うとするなら
デストラクタの呼び出しを伴わない終わり方(exitとかSIGKILL)をすると
いろいろと面倒だよねって話。


うーん、exit派なんだけど、ちょっと心が揺らいできた。
throwしよっかな。
でもめんどくさいw
183デフォルトの名無しさん:2008/08/03(日) 20:19:12
>>182
悪いことは言わん、exit も throw もやめとけ。
どちらもあくまで緊急脱出手段だ。
184デフォルトの名無しさん:2008/08/03(日) 20:29:18
デストラクタの役割がメモリ解放だけだと思ってるうちは初心者
185デフォルトの名無しさん:2008/08/03(日) 20:43:10
>>184
他にどのような利用をするのですか?
186デフォルトの名無しさん:2008/08/03(日) 20:57:12
187デフォルトの名無しさん:2008/08/03(日) 21:08:54
>>180
入出力チャンネルって何?

ハンドルなら自動的にクローズされるけど
188デフォルトの名無しさん:2008/08/03(日) 21:17:28
exitなんて使ったら、名前付きパイプとかWindowsフックみたいな
プロセスを越えるリソースが開きっぱなしでリークするな。

他にもメモリキャッシュ実装しててflushされないとか、
キャッシュファイルが削除されないとか、
Excelみたいなファイル内に共有ロック情報書いてる場合にアンロックされないとか
リソースリーク/終了処理が正常に行われないケースは山ほどある。
189デフォルトの名無しさん:2008/08/03(日) 21:36:07
されねーよ。
どのプロセスがどのnamed pipeを開いているかぐらい余裕で把握している。
すべてのプロセスが解放したら消させる。

フックも把握していないといずれ面倒なことになる。

それにVistaからは、フック関数側のCallNextHookEx呼び出しに頼らず、
Windows側がひとつひとつ呼んでいるってのをどこかで呼んだ気がするが。
190デフォルトの名無しさん:2008/08/03(日) 21:37:41
exit使ったって正常に動くプログラムは書けるが

そんなプログラムを書く奴は人に信用されない
無学に見られるから止めておくほうがよろし
191デフォルトの名無しさん:2008/08/03(日) 21:39:43
>>188
言いたいことはよくわかるが
exit なんぞ平気で使う奴には通じない話だ
192デフォルトの名無しさん:2008/08/03(日) 21:47:35
190に補足すると
作成者が注意力を発揮すれば exit 使う正しいプログラムは書けるが
ちょっとした改造の度にそんなところに注意力を使わなければならない時点で
稚拙な設計だ

優秀なプログラムは、無駄なバグ混入リスクを取らないよう書かれている
で、ホントに必要なときに限りテクを使う
193デフォルトの名無しさん:2008/08/03(日) 21:55:56
ところで、デストラクタでリソース解放するのって優秀なの?
194デフォルトの名無しさん:2008/08/03(日) 21:58:06
エラー処理できないのでダメダメ
195デフォルトの名無しさん:2008/08/03(日) 21:59:40
>>193
他の方法ではまともに例外安全なコードが書けない
196デフォルトの名無しさん:2008/08/03(日) 22:00:26
auto_ptrやsmart_ptrをダメダメだと言い捨てるとは、勇者だな。

んじゃ教えてくれ。
リソースの解放でエラーが発生したら、一体どうすりゃええんだ。
197デフォルトの名無しさん:2008/08/03(日) 22:01:00
すみませんが、助けていただけないでしょうか。
ttp://www.geocities.jp/menopem/
こちらのDirectXウィンドウ化ツールで使用する補助DLLとして、
「窓化起動したアプリケーションを再びフルスクリーン化する」
というものを制作したいのですが、C++の経験が無いために苦しんでいます。
補助DLLの仕様についてはツール内にtxtで含まれているのですが・・・。

用途としてはどうしても色化けしてしまう古い(256色専用)ゲームをパレットエミュレートで正常に動かすことが目的なのですが、
窓化した場合、窓の描画領域の0.0をディスプレイの0.0に合わせないと、画面描画や文字描画がその分ずれてしまう現象に見舞われてしまったので、その簡易な修正のためです。
問題のゲームは下のデザートタイム夢幻の迷宮とファントムナイト夢幻の迷宮Uです。
ttp://www.parsley.gr.jp/ps_top1.html (リンク先18禁)
198デフォルトの名無しさん:2008/08/03(日) 22:02:08
>197続き
一応書いてみたコード。ウィンドウハンドルとか判りませんorz
#include <windows.h>
#include <stdio.h>

BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
static TCHAR  processName[MAX_PATH];

switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
GetModuleFileName(0, processName, MAX_PATH);
processName[MAX_PATH-1] = '\0';

OutputDebugString("補助DLLロード確認");
MessageBox(0, processName, "補助DLLロード確認",  MB_OK);

SetWindowLong(HANDLE, GWL_STYLE, WS_POPUP | WS_MINIMIZEBOX | WS_VISIBLE);
SetMenu(HANDLE, NULL);
SetWindowPos(HANDLE, HWND_TOP, 0,0,1400,1052, SWP_FRAMECHANGED | SWP_NOCOPYBITS);

break;

case DLL_PROCESS_DETACH:
OutputDebugString("補助DLLアンロード確認");
MessageBox(0, processName, "補助DLLアンロード確認",  MB_OK);
break;
}
return TRUE;
}
199デフォルトの名無しさん:2008/08/03(日) 22:02:26
DirectXスレに行って下さい
200199:2008/08/03(日) 22:05:18
訂正、Win32APIスレへ
ClientToScreen、GetWindowRectなど
201デフォルトの名無しさん:2008/08/03(日) 22:08:04
>>194
例外安全でエラー処理出来る方法を、世界中で多くの人が求めています。
教えてあげて下さい。
202デフォルトの名無しさん:2008/08/03(日) 22:08:08
>>195
ぜひkwsk
203デフォルトの名無しさん:2008/08/03(日) 22:12:47
>>196
releaseとかcloseのような名前の解放用メンバ関数を用意しておいて、
エラー処理が必要ならそれを明示的に呼び、要らなければデストラクタに任せるとかいう話を聞いたことがある。
204デフォルトの名無しさん:2008/08/03(日) 22:15:44
>>202
//RAIIなコード
void fn1(){
   File fR;
   File fW;
   fR.open("read.txt");
   fW.open("write.txt");
   fn3(fR, fW);
}
//デストラクタに頼らずリソースを解放するコード
void fn2(){
   File fR;
   File fW;
   fR.open("read.txt");
   fW.open("write.txt");
   try{ fn3(fR, fW); }
   catch(...){
      try{ if(fW.opend()){fW.close();} }
      catch(...){
         if(fR.opend()){fR.close();}
         throw;
      }
      if(fR.opend()){fR.close();}
      throw;
   }
   try{ if(fW.opend()){fW.close();} }
   catch(...){
      if(fR.opend()){fR.close();}
      throw;
   }
   if(fR.opend()){fR.close();}
}
205デフォルトの名無しさん:2008/08/03(日) 22:23:05
RAII様様
GCよりよっぽど使えるわ
206デフォルトの名無しさん:2008/08/03(日) 22:25:54
それは言いすぎな気がするけど、だからこそC++を使う気になるのは俺もそう。
207デフォルトの名無しさん:2008/08/03(日) 22:27:53
>>204
サンクス。
208デフォルトの名無しさん:2008/08/03(日) 22:28:31
RAIIのほうは解放に失敗したらハンドルリークするから駄目だね
209デフォルトの名無しさん:2008/08/03(日) 22:30:36
ついでにGCがあるjavaとC#も。
リソースのcloseに関してはjavaがもっともカス。

//java
void fn2(){
   InputStream ist = new FileInputStream("a");
   try{
      OutputStream ost = new FileOutputStream("b");
      try{
         fn3(ist, ost);
      }
      finally{ try{ ost.close(); }catch(Throwable t){} } //(*1)
   }
   finally{ try{ ist.close(); }catch(Throwable t){} }
}
//(*1) catchで止めないとより重要なfn3内の例外が消される

//C#
void fn2(){
   using(StreamReader r = new StreamReader("a"))
   using(StreamWriter w = new StreamWriter("b"))
   {
      fn3(r, w);
   }
}
210デフォルトの名無しさん:2008/08/03(日) 22:31:32
>>208
>ハンドルリークするから
しません。それただのバグ。
211デフォルトの名無しさん:2008/08/03(日) 22:32:30
>>208
解放処理が失敗してどうやって解放するの?
プロセスを終了してOSに任せるくらいしか俺には分からない。

もし、デストラクタが例外投げた場合の話であれば、そもそもそれが間違いだよな。
デストラクタは何があろうと例外を投げちゃまずいよ。
212デフォルトの名無しさん:2008/08/03(日) 22:38:12
Dはまだscoped_ptrなRAIIがあるからいいけど,それすらない
C#,Javaだとリソースの解放マンドイよな
213デフォルトの名無しさん:2008/08/03(日) 22:42:45
>>210
> しません。それただのバグ。

失敗はするでしょ。
成功するまでループするの?
214デフォルトの名無しさん:2008/08/03(日) 22:44:50
>>213
しません、は「リークする」にかかってるんでしょ。
215デフォルトの名無しさん:2008/08/03(日) 22:49:18
解放失敗すればリークするだろ
216デフォルトの名無しさん:2008/08/03(日) 22:54:13
解放に失敗するリソースをどうやって解放するんだ
もはやリークは避けられない運命としか
217デフォルトの名無しさん:2008/08/03(日) 22:54:48
>>215
>>208の人は「RAIIのほうは」って言ってるんだし、
解放失敗すればリークってのはRAII関係無いだろ。
脈絡の無いレスは止めておいた方がいい。
218デフォルトの名無しさん:2008/08/03(日) 22:55:09
明日死ぬかもしれないだろ
219デフォルトの名無しさん:2008/08/03(日) 22:55:49
>>215
では、RAIIを使用せずに開放メンバ関数を手動で呼べばリークしないんですね
220デフォルトの名無しさん:2008/08/03(日) 22:56:36
>>218
唐突過ぎて不覚にもワロタ
221デフォルトの名無しさん:2008/08/03(日) 23:00:43
まあ以下>>208はスルーで
アホは放置
222デフォルトの名無しさん:2008/08/03(日) 23:08:24
>>211
>>204って解放に失敗したらデストラクタから例外投げるよって意味じゃないの?
そうでなければ、

    try{ fn3(fR, fW); } catch(...) { }
    try{ if ( fW.opend() ) { fW.close(); } } catch (...) { }
    try{ if ( fR.opend() ) { fR.close(); } } catch (...) { }

とかいう暴挙に出てもいいのかな。
223デフォルトの名無しさん:2008/08/03(日) 23:16:18
>>222
fn3の例外は潰したら駄目。
他はまぁアリかな。
224デフォルトの名無しさん:2008/08/03(日) 23:31:12
>>166の"ギリギリ"ってプログラムに拠るって意味かね?
それとも、クライアントプログラムでもサーバープログラムでも、
1年かかって計算するようなプログラムでも、"本当に不可避な場合"だけを指してるのかな?

おれは前2者しかやったことないから、それ以外がよく分からないんだけど、
クライアント側ならOKと判断してたし、サーバー側も月一回程度の再起動はゆるされたんで、
"ギリギリ"がよく分からない。 よかったら教えて欲しい。
225デフォルトの名無しさん:2008/08/04(月) 00:02:57
>>183
throwもやめとけって、じゃあどうするの?
226デフォルトの名無しさん:2008/08/04(月) 00:09:32
>>225
異常系はかまわんけど、正常系で throw で抜けるはよせ。
return で main() まで帰れ。
227デフォルトの名無しさん:2008/08/04(月) 00:12:08
>>226
異常系って言うと、メモリが足りないとか、電力が足りないとか?
228デフォルトの名無しさん:2008/08/04(月) 00:19:12
頭が足りないとか。
229デフォルトの名無しさん:2008/08/04(月) 00:24:14
>>227
throw の使い方は派閥があるみたいだけど、俺は寛容派なんでファイル
オープンに失敗した程度のエラーや、ユーザーがキャンセル操作を行った
程度のことでも throw を使っていいと思う。
230デフォルトの名無しさん:2008/08/04(月) 00:49:30
テンプレートクラス内テンプレートクラスの演算子オーバーロードをしたいのですが、
どのように記述すればよいでしょうか?

例えば、
template< int m > struct foo{
 template< int n > struct bar{};
};
に対して、operator*( int, foo<m>::bar<n> )を定義したいのですが、
fooのクラス内静的関数として定義すると怒られますし、
グローバルな領域で
template< int m, int n > foobar operator*( int, foo<m>::bar<n> )
とやってもやはりコンパイルが通りません。
231デフォルトの名無しさん:2008/08/04(月) 00:53:32
>>229
プロジェクト内で一貫した方針で使ってる分にはいいんじゃないかと思う。
232224:2008/08/04(月) 01:07:07
無視されてるのか勘違いされてるのか、よくわからないけど、
とりあえずあいまいな質問だったし、>>229が答えのような気がするので、
お礼いってたいさんします。 さんくす。
233デフォルトの名無しさん:2008/08/04(月) 01:09:08
煽ってたわけじゃなくて、本気で聞いてたのか……
234232:2008/08/04(月) 01:38:27
>>233
すいません、本気でした。。
235230:2008/08/04(月) 02:24:03
template< int m, int n > foobar operator*( int, typename foo<m>::template bar<n> )
でとりあえず自己解決したような気がします、すいません。

それにしてもこんなところにtemplateをつける用法があるんですね。
236デフォルトの名無しさん:2008/08/04(月) 09:52:02
RAIIだとハンドルリークする
について、まともな反論は結局なかったな

なんであんな誤った手法がまかり通ってるんだろうな
237デフォルトの名無しさん:2008/08/04(月) 10:08:39
>>236
RAIIだとハンドルリークする
について、まともな主張は結局なかったな
238デフォルトの名無しさん:2008/08/04(月) 10:13:27
>>236
俺の誤解でなければ、>>208と同じ人or意見ということだよな?

そもそも>>208自体が説明出来ていないので、
反論以前に、まともな主張になっていないわけだけど。

釣りかな?
239デフォルトの名無しさん:2008/08/04(月) 14:45:58
CloseHandleが失敗したらハンドルリークするんですが、どうすればいいんですか><
240デフォルトの名無しさん:2008/08/04(月) 14:55:24
>>239
何事も完璧を求めると大変です。
どうやっても閉じれないハンドルなど捨ておきなさい。
241デフォルトの名無しさん:2008/08/04(月) 14:59:40
close失敗したハンドルって普通リークしたって言わないよね
242デフォルトの名無しさん:2008/08/04(月) 15:08:34
CloseHandleが失敗する原因を突き止めてください。
243デフォルトの名無しさん:2008/08/04(月) 15:41:16
普通はログ吐くよね
吐けな(ry
244デフォルトの名無しさん:2008/08/04(月) 19:16:59
グローバル変数やグローバル関数に一律で大域識別子::を付けるというのは
C++では当たり前ですか?確かに名前の衝突は起きにくくなりますが
いちいち付けるのもなぁとも。やっぱり大規模なプログラムなんかだと
そうやっといたほうが良いのですかねぇ。
245デフォルトの名無しさん:2008/08/04(月) 19:25:44
必要なら付けろ。
不要なら付けるな。
よほど変なルールじゃなければ従え。
246デフォルトの名無しさん:2008/08/04(月) 21:10:12
RAII使っても使わなくてもCloseHandleに失敗したときの対応はニタリヨッタリじゃない?
RAIIの欠点としては弱いのでわ?RAII使うメリットを考えるとRAIIダメとは思わないなあ。
247デフォルトの名無しさん:2008/08/04(月) 21:21:43
何を言ってるんだ。
248デフォルトの名無しさん:2008/08/04(月) 21:23:45
>>239
情報隠蔽の基本からやり直せ
249デフォルトの名無しさん:2008/08/04(月) 22:26:03
RAIIってリソース破棄の順序も制御できるのかな。
ファイル書き出し → アンマウント みたいに。
250デフォルトの名無しさん:2008/08/04(月) 22:38:46
>>249
RAII≒デストラクタ
後はもう自明だろう
251デフォルトの名無しさん:2008/08/05(火) 08:58:00
>>249
アンマウントに失敗したらリークどころじゃなくなるからRAII方式はやめとけ
252デフォルトの名無しさん:2008/08/05(火) 09:57:46
キチガイが沸いているようですね
253デフォルトの名無しさん:2008/08/05(火) 10:20:30
APIの戻り値はチェックして当然だよな。


class HandleWrapper
{
 HandleT handle;
public:
 //...
 ~HandleWrapper() {
  while ( CloseHandle(handle) != SUCCEEDED ) {
   ;
  }
}
};

254デフォルトの名無しさん:2008/08/05(火) 10:35:46
ループするならユーザー通知くらいは。

struct NoRetry{
 bool userRetryWait(HandleT handle){return false;}
};
template<typename T=NoRetry> class HandleWrapper{
 HandleT handle;
 T rt;
public:
 //...
 ~HandleWrapper(){
  while (CloseHandle(handle) != SUCCEEDED){
   if(!rt.userRetryWait(handle)){break;}
  }
 }
};
255デフォルトの名無しさん:2008/08/06(水) 18:17:59
auto_ptr見てたら演算子のオーバーロードがよくわからなくなってきました。

struct st
{
int Int;
};
class test
{
st Data;
public:
st *operator->() { return &Data; };
st *Get() { return &Data; };
};

test obj;
int i = obj->Int;
 これが出来るなら
int i = obj.Get()Int;
 これも出来そうな気がしたけど出来ない。
そもそも->演算子ってどんなものなんでしょうか?
256デフォルトの名無しさん:2008/08/06(水) 18:30:30
>>255
それやるなら、obj.Get()->Int

多重定義された->演算子は変わりもので、それを呼び出してその戻り値に再び->演算子を適用するようになっている。
つまり、obj->Intはobj.operator ->()->Intと解釈される。
257デフォルトの名無しさん:2008/08/06(水) 18:45:10
>>256
>obj->Intはobj.operator ->()->Int
こんな解釈されるんでしたか・・。
ありがとう。勉強になった。
258デフォルトの名無しさん:2008/08/07(木) 15:45:36
例外処理についての質問です
try内部でエラーが発生してcatchに移行する場合など、若干動作が遅いという話を耳にしました

それは納得なのですが、例外が発生しない場合はどれだけtry catchを繰り返したりネストしても
例外が発生しない限り処理速度は低下しないのでしょうか?
259デフォルトの名無しさん:2008/08/07(木) 15:49:06
登録と解除のオーバーヘッドはある
260デフォルトの名無しさん:2008/08/07(木) 15:50:19
まーほぼすべての処理系では、
tryのブロックに入るたびに、例外のために必要なものスタック上に構築するので
tryブロックに出入りするたびにコストがかかる。


だから、これは問題ない
try {
for(;;){/**/}
}

問題あり
for (;;)
{

try { /**/}

}
261デフォルトの名無しさん:2008/08/07(木) 15:56:39
即レスどうもです。
と言うことは例えばmainの最初にtry、最後にcatchして内部でどれだけ処理したとしても
try catchしない場合と比べてオーバーヘッドは略ゼロに等しいということですね。

これで安心して例外処理ベースで組めそうです。ありがとう。
262デフォルトの名無しさん:2008/08/07(木) 16:19:48
struct{
float _11, _12, _13, _14;
float _21, _22, _23, _24;
float _31, _32, _33, _34;
float _41, _42, _43, _44;
};
上記のようなマトリックスのクラスで、
>m[1][2]のようにアクセスできるように演算子[]を多重定義せよ
という課題があるのですが可能なのでしょうか?いくら検索しても
やり方のヒントも出てこないのですが…
263デフォルトの名無しさん:2008/08/07(木) 16:25:23
つunion
264デフォルトの名無しさん:2008/08/07(木) 16:27:52
具体的にはこう

union{

struct{
float _11, _12, _13, _14;
float _21, _22, _23, _24;
float _31, _32, _33, _34;
float _41, _42, _43, _44;
};

float m[4][4];

}

何でそれで出来るかは考えてね
265デフォルトの名無しさん:2008/08/07(木) 16:40:50
どこで演算子をオーバーロードしてるのか問い詰めたい。小一時間問い詰めたい。
266デフォルトの名無しさん:2008/08/07(木) 16:44:55
オーバーロードしてませんすみませんorz
267デフォルトの名無しさん:2008/08/07(木) 17:00:14
反省して真面目に考えた
float* operator [](int n) { return &((&_11)[n*4]); }

[0][0]で_11
[1][2]で_23
になるんじゃないかな

行と列を逆にしようとするとめんどいな・・・
268デフォルトの名無しさん:2008/08/07(木) 17:27:18
switch手書きの手間なんか惜しむな

#include <stdexcept>
struct hoge;
struct proxy{
hoge&o;
int i;
proxy(hoge&o,int i):o(o),i(i){}
float operator[](int);
};
struct hoge{
/*略*/
proxy operator[](int i){return proxy(*this,i);}
};
float proxy::operator[](int j){
switch(i){
case 1:switch(j){
case 1:return o._11;
case 2:return o._12;
case 3:return o._13;
case 4:return o._14;
default:throw std::invalid_argument("damepo");
}
/*略したのは「改行が多すぎます」といわれたからであって、決してサボろうとした訳では(ry*/
default:throw std::invalid_argument("damepo");
}
}
269デフォルトの名無しさん:2008/08/07(木) 17:30:51
変数の定義が可能な位置について教えてください。
if(...){
 int a;
}
これはだめですよね。ただ
for(;;){
 int a;
}
これってg++では定義できないスコープということでエラーがでますが、
Effective C++のサンプルコードでfor文のスコープでオブジェクトを
定義していたのですが、Effective C++が間違ってるのでしょうか?
270デフォルトの名無しさん:2008/08/07(木) 17:34:48
>>269
C++の話なら変数の宣言の位置にそのような制約はない。
271デフォルトの名無しさん:2008/08/07(木) 17:36:45
>>269
C言語でも無問題。
どうして
> これはだめですよね。
と思ったのかkwsk
272269:2008/08/07(木) 17:39:54
あ、すいません、自分の勘違いでした^^;
273269:2008/08/07(木) 18:13:46
いろいろ試して遊んでたら
switch(i){
 case 1: int a = 1;
 case 2: int b = 2;
}
こんなんダメみたいですね。caseラベルによって初期化が飛ばされるとかで。
 case 1: int a;
 case 2: int b;
これならいいみたいですけど。
274デフォルトの名無しさん:2008/08/07(木) 18:14:03
>>267>>268
返答有難うございます。その方法で試してみます。

ちなみに検索しても見つからなかったのは、[][]なんで
float* operator [][](int a,int b)
のようにするのかと勘違いしてたからでしたorz
275269:2008/08/07(木) 18:28:42
switch(i){
 case 1: int a;
 case 2: int b = 2;
}
これだと問題ないみたい。
switch(i){
 case 1: int a;
 case 2: int b;
 case 3: int c = 3;
}
これも問題なし。
つまり最後のラベルの位置でのみ初期化指定子が書ける模様。
なんでだろ。
276デフォルトの名無しさん:2008/08/07(木) 18:33:16
フォールスルーするからに決まってるだろ
277269:2008/08/07(木) 18:34:28
それが
switch(i){
 case 1: int a; break;
 case 2: int b; break;
 case 3: int c = 3;
}
これも問題ないんですよね。
278デフォルトの名無しさん:2008/08/07(木) 20:39:25
>>275
それより後ろに飛ばないから
つまり初期化をスキップしない
279デフォルトの名無しさん:2008/08/07(木) 20:39:55
黙って { } つけれ
280269:2008/08/07(木) 21:09:38
switch(i){
 case 1: int a; break;
 case 2: int b; break;
 case 3: int c = 3;
}
このコードでcase 3に飛んだ場合、aやbのインスタンスは確保されないって
ことでいいの?
281デフォルトの名無しさん:2008/08/07(木) 21:15:17
最適化されたらされないかもしれません。きっとcも確保されないでしょう。
282デフォルトの名無しさん:2008/08/07(木) 21:22:37
>>280
これがコンパイルできない理由を考えれば
事態が把握できますか?

struct X { X(){} };

void f(int a)
{
switch (a) {
case 1: X x; break;
case 2: X y;
}
283デフォルトの名無しさん:2008/08/07(木) 22:57:36
質問です。
HogeA と HogeB の2つのクラスがあり
HogeA と HogeB が互いに所持しあうような場合
ファイルを分けるとしたらどのようにすればいいのでしょうか
以下のような書き方だとエラーになってしまいます
*********************************
FILE_A.h
*********************************
#ifndef HOGEA
#define HOGEA
#include "FILE_B.h"
class HogeA {
HogeB* m_pHogeB;
public:
HogeA() { m_pHogeB = new HogeB() }
}
#endif
*********************************
FILE_B.h
*********************************
#ifndef HOGEA
#define HOGEA
#include "FILE_A.h"
class HogeB {
HogeA* m_pHogeA;
public:
HogeB() { m_pHogeA = new HogeA() }
}
#endif
284デフォルトの名無しさん:2008/08/07(木) 22:58:22
まちがえました。
FILE_B.hの最初の2行は
#ifndef HOGEB
#define HOGEB
です
285デフォルトの名無しさん:2008/08/07(木) 23:11:34
>>283
先行宣言しろ
286デフォルトの名無しさん:2008/08/07(木) 23:16:01
仮にコンパイル通したとしてもメモリ食いつぶすかスタックオーバーフローで落ちると予想
設計がおかしいぞ
287デフォルトの名無しさん:2008/08/08(金) 01:31:14
>>283
そういうのは普通、所持しあうとは言わないと思うよ。
オブジェクトを作りあう……とか?

それはそうと、コンパイルを通すには、メンバ関数の定義を外に出せ。

// FILE_A.h
...
class HogeA{
...
HogeA();
}

// FILE_A.cpp
#include "FILE_A.h"

HogeA::HogeA() { m_pHogeB = new HogeB() }

// Bも同様

まあ、もちろんこれで通っても>>286の通りだが。
288デフォルトの名無しさん:2008/08/08(金) 01:35:18
ある意味再帰的だな
289デフォルトの名無しさん:2008/08/08(金) 04:59:47
>>259-260
try ブロックの出入りでオーバーヘッドが発生する処理系は、今はもうだいぶ
減ってきてると思うよ。 Windows では長らくオーバーヘッドがある実装ばかりだった
けど、今は VC++ も「同期例外」とかいうオプションで選択できるようになってたと思う。
290デフォルトの名無しさん:2008/08/08(金) 07:26:23
>>285-288
ありがとうございました
コンストラクタでnewしてるのは単純な例として書いたつもりでしたが
確かにメモリを食いつぶすかループしてしまいそうですね
291269:2008/08/08(金) 07:57:24
>>282
う〜ん、デフォルトコンストラクタも初期化子と同等と考えれば
コンパイルできないのも組み込み型のときと同じと考えられますが…
switch (a) {
case 1: break;
case 2: X y;
}
これならコンパイルできますね。
要は、インスタンスの確保や初期化は、その位置に制御が来たときにだけ
されるのかどうか?ということです。もしそうなら、一番下のラベルの所だけ
初期化が許されるというのは解せないというか。けっきょく一番下のラベルも
実行時に飛ばされる場合もあるわけだし…他の上の方のラベルと同等と考え
られそうな気も…。
292デフォルトの名無しさん:2008/08/08(金) 08:11:13
>>292
だから、宣言部をスルーして有効な範囲に飛び込んじゃダメなの。
要は、
{
goto foo;
int x;
foo:
}
はNGで
{
goto foo;
int x;
}
foo:
はOK。
293デフォルトの名無しさん:2008/08/08(金) 08:12:37
いけね、レス番ずれた。
{
int x;
goto foo;
}
foo:
がOKなのは言うまでもないし。
294269:2008/08/08(金) 09:53:56
NGというパターン
{
goto foo;
int x;
foo: 0;
}
は、問題ないみたいですよ。
ただ、
{
goto foo;
int x = 1;
foo: 0;
}
はダメでした。
つまり、定義ではなく、初期化を飛び越すのがダメみたいですね。
初期化子やコンストラクタ呼び出しが該当するようです。
つまり、飛び越された場合、初期化はされてないけど、同じスコープだから
そのインスタンスは使用可能。こういう状況を避けたいがための、エラー
なのかもしれませんね。なんか納得できたかもしれません。
295デフォルトの名無しさん:2008/08/09(土) 20:05:08
前者も NG であるべき
296293:2008/08/09(土) 20:43:32
すまん、>292の前者だと警告だけなんだ。
297デフォルトの名無しさん:2008/08/09(土) 21:41:48
>>292の前者だと、foo:ラベルの後に何の式もなくブロックが終わってる
ことに対して、エラーになるけど、>>294みたいに0;とか追加すれば
エラーも警告も出ないけどなぁ、VC++でもg++でも。
298デフォルトの名無しさん:2008/08/09(土) 21:55:49
gotoで変数定義を飛び越えるのはなんら規格に反していない
299デフォルトの名無しさん:2008/08/09(土) 21:59:23
規約には反しているかも知れない。
300デフォルトの名無しさん:2008/08/09(土) 22:11:52
規格で認められてるからいいんだだの、gcc が警告しないからいいんだだの、そんな判断基準にしがみついていたければ勝手にしれ
301デフォルトの名無しさん:2008/08/09(土) 22:13:59
じゃあお前の判断基準は何だよw
302デフォルトの名無しさん:2008/08/09(土) 22:19:23
おまえに言ってもわからなそうだが、設計哲学ってやつだ
303デフォルトの名無しさん:2008/08/09(土) 22:23:24
お前の様なバカがいるからポーティングに苦労すんだよ
304デフォルトの名無しさん:2008/08/09(土) 22:27:47
同意、>>302みたいな馬鹿がいるから困る
305デフォルトの名無しさん:2008/08/09(土) 22:30:37
設計哲学なんて、主観の問題じゃねぇかw
人に押しつけるもんでもない。
規格で許されてるかどうかの話してるところへ
哲学がどうとか、頭沸いてるんじゃねぇか?w
306デフォルトの名無しさん:2008/08/09(土) 22:39:08
設計哲学、大切だろ・・・。
好き勝手にみんなで俺様オナニーコード書いてたら
現場は困るだろ。

まあ、お前らは自分の身を守れるのかもしれんがな。
307デフォルトの名無しさん:2008/08/09(土) 22:55:13
>>306
哲学うんぬんはいいとして
俺様オナニーコードでも無駄がなくて仕様どおりなら特に困らないよ
308デフォルトの名無しさん:2008/08/09(土) 22:57:37
>哲学うんぬんはいいとして
は良いと思ってるんじゃなくてどうでもいいってことね
309デフォルトの名無しさん:2008/08/09(土) 23:29:04
設計の良し悪しを考えずに作られたプログラムは
再現率の低い組み合わせ入力や、異常な入力に弱いことが多いからダメ
検査時に再現させられるパタンなんて限られているからね
310デフォルトの名無しさん:2008/08/10(日) 01:52:23
「設計哲学」と「好き勝手にみんなで俺様オナニーコード」が違うと言うなら、
設計哲学ってのが何を指しているのかを明らかにしないと。
311デフォルトの名無しさん:2008/08/10(日) 01:56:15
boostに嵌るとついついオナニーコード書いてしまうよね
でも楽しくて仕方ないんだ
312デフォルトの名無しさん:2008/08/10(日) 02:02:11
コードレビューなし前提の話ばかりだ
みなさんダメプロジェクトにいるんですね
313デフォルトの名無しさん:2008/08/10(日) 02:32:19
コードレビューやりたいって言ったんだがする気配はない
正直最低限の規約も守れない奴ばっかなのでちゃんと勉強して欲しいんだけどねぇ
314デフォルトの名無しさん:2008/08/10(日) 02:43:02
>>313
他のメンバーがコミットしたコードを勝手にレビューすればいいんだ
で、最初は簡単で明白な改善を提案していけば良いんじゃない?
315デフォルトの名無しさん:2008/08/10(日) 02:47:10
達人プログラマーの石のスープパターンだ
316デフォルトの名無しさん:2008/08/10(日) 02:54:37
インクリメンタルなイテレーション

とか書いてある本をいくら読んでもどうしたらいいのかわかりません。
横文字多すぎだよ。
317デフォルトの名無しさん:2008/08/10(日) 09:14:50
incrementalなiterationの方が読みやすいということですね、わかります

俺も割とそう思う
318デフォルトの名無しさん:2008/08/10(日) 11:01:31
C/C++でコードレビューは必須だろ
「C/C++できます」
の「できます」の意味が広すぎる

少なくとも一回は見ないとそいつがどの程度がわからないし
俺よりすごい人ならそいつにレビューお願いできるし
319デフォルトの名無しさん:2008/08/10(日) 11:51:54
EffectiveC++も読んでない奴とは仕事したくない、ってのはさすがに我侭だろうか
320デフォルトの名無しさん:2008/08/10(日) 11:53:26
Effective C++に書かれていることを独学で理解しているなら読んでなくてもいい。
読んでても理解してない奴もいるし。
321デフォルトの名無しさん:2008/08/10(日) 13:12:18
Effective C++は正直言って微妙。
Exceptional C++に書いてある事を理解しててくれたら十分
322デフォルトの名無しさん:2008/08/10(日) 13:42:05
例外安全て説明すんの意外と面倒なんだよな・・
323デフォルトの名無しさん:2008/08/10(日) 14:47:02
例外安全ってなんだっけ・・・
例外が発生したとき、オブジェクトの状態はその関数の呼び出し前の状態から変更されていない?
324デフォルトの名無しさん:2008/08/10(日) 15:05:26
>>323
//例外安全でない、f()がthrowしたらnew A()がdeleteされない\(^o^)/
void f(){
  A* a = new A();
  f(a);
  delete a;
}

//例外安全、f()がthrowしてもdeleteされる
void f(){
  auto_ptr<A> a(new A());
  f(a.get());
}
325デフォルトの名無しさん:2008/08/10(日) 15:08:14
>>323
そんな感じ。

しかし例外に限らず戻り値でのエラー通知でも同様の安全性は
考えるべきだから、これはエラー安全性と言うべきだ。

http://www.gotw.ca/sands2.htm
Error-Safe C++: More Than Just Exception Safety (Bjarne Stroustrup & Herb Sutter)
> But we'll also cover error safety in all cases, because the main difficulty
> in writing exception-safe code has little to do with exceptions in particular,
> but with error handling in general
326324:2008/08/10(日) 15:08:47
ごめん、f2(a);、f2(a.get());、f2()がthrowしたら、に読み替えて
327デフォルトの名無しさん:2008/08/10(日) 15:18:17
>>323
日本語の包括的な文書が見つからなかった
http://www.boost.org/community/exception_safety.html
書籍ならハーブ・サッターの Exceptional C++ が有名
328デフォルトの名無しさん:2008/08/10(日) 15:28:00
簡単に言うと、デストラクタ以外の
どんな関数・暗黙の呼び出しから例外が出てもリークしないようにする、ってこと
329デフォルトの名無しさん:2008/08/10(日) 15:30:19
レースコンディションの親戚みたいな
330デフォルトの名無しさん:2008/08/10(日) 15:34:14
それはさすがにちがうだろ
331デフォルトの名無しさん:2008/08/10(日) 15:59:32
>>328が「基本保証」。
ある処理で例外が発生してその処理を抜けたとき、副作用が起きない
(またはその処理による副作用が起きる前の状態に復元される)ことの保証が「強い保証」。
どのような状況でも例外が発生しないことの保証が「投げない保証」。
332デフォルトの名無しさん:2008/08/10(日) 16:12:15
実際にみんなはどの程度例外実装してる?
結局後回しになって基本保証程度になってしまう
333デフォルトの名無しさん:2008/08/10(日) 16:14:56
>>332 何が後回しになるって?
334デフォルトの名無しさん:2008/08/10(日) 16:29:40
>>333
例外保証の実装
とりあえず例外処理の流れと簡単な処理は組み込むけどしっかりした実装はデバッグ工程でつめていく感じ
といってもデバッグ期間がほとんどないスケジュール組まれるので大抵時間なくなるという話
335デフォルトの名無しさん:2008/08/10(日) 16:37:11
DB使ってるから、全部ではないけど大体は強い保証になってる。
336デフォルトの名無しさん:2008/08/10(日) 16:38:13
とりあえず強い保証程度はできる限りやってる
337デフォルトの名無しさん:2008/08/10(日) 16:50:36
>しっかりした実装はデバッグ工程

それ設計じゃね?

338デフォルトの名無しさん:2008/08/10(日) 16:57:20
例外安全について指摘してくれる静的解析ツールとかあればいいんだけどな
339デフォルトの名無しさん:2008/08/10(日) 17:33:42
>>334
最初からちゃんと書けばいいだけじゃないの?
340デフォルトの名無しさん:2008/08/10(日) 19:22:02
後付けで基本保証から強い保証に上げたりするのは困難だろ。
小手先の話じゃないんだから。
341デフォルトの名無しさん:2008/08/10(日) 19:51:26
計算量が O(1) から O(N) になることもあるからね
実装自体は小手先の話だけど
342デフォルトの名無しさん:2008/08/10(日) 21:53:44
連想コンテナの定義って何?
てっきり、常に整列されてるコンテナのことかと思ったけど、
ハッシュテーブルも連想コンテナの一種らしいね。
ハッシュって整列されてないやろ?
343デフォルトの名無しさん:2008/08/10(日) 21:55:21
整列されてるかどうかじゃなくて、
任意の型(文字列とか)をキーに一意に値を求められるもの
と俺は思ってたけど
344デフォルトの名無しさん:2008/08/10(日) 21:56:11
345デフォルトの名無しさん:2008/08/10(日) 21:59:10
>>343
それは連想配列という認識だったけど、もしかして連想コンテナと
連想配列って同義語?
346デフォルトの名無しさん:2008/08/10(日) 22:01:28
連想コンテナならハッシュかニ分木。
連想配列なら多分ハッシュに限定。
347デフォルトの名無しさん:2008/08/10(日) 22:15:22
mapも連想配列って言うらしい。
配列のインデックスに値だけじゃなくて、文字列などの自由な型が使えるものを
連想配列と言うらしい。

連想コンテナの例:set, multiset, map, multimap, hash
連想配列の例:map, hash

こうか?連想コンテナの定義が浮かばないけど。
348デフォルトの名無しさん:2008/08/10(日) 22:18:27
349デフォルトの名無しさん:2008/08/10(日) 22:19:37
一般的に配列はコンテナに含まれるし、全部まとめて連想コンテナでいいのかな
350デフォルトの名無しさん:2008/08/10(日) 23:11:53
Cではコンテナは配列しかなかったから、
コンテナ全部配列と呼んでたような理由かな。
351デフォルトの名無しさん:2008/08/10(日) 23:12:26
組み込み型にはデフォルトコンストラクタという概念はないのでしょうか。
int(), double()などは0を返すので、論理的にはデフォルトコンストラクタを
持ってるのかと思いきや
class hoge{
 int i
};
このhogeクラスをデフォルトコンストラクタで生成しても、iは0で初期化
されない(intのデフォルトコンストラクタが呼ばれない?!)あたり、
やはり組み込み型には論理的にもデフォルトコンストラクタは持っていない
ということですか?
352デフォルトの名無しさん:2008/08/10(日) 23:15:47
class hoge {
int i;
hoge() : i() {}
};
353デフォルトの名無しさん:2008/08/10(日) 23:19:59
いや、なんていうか、クラスのメンバオブジェクトに対してはそれぞれ
自動でデフォルトコンストラクタが呼ばれるのに、何で組み込み型は
デフォルトコンストラクタ(存在するなら)が呼ばれないのかなと。
354デフォルトの名無しさん:2008/08/10(日) 23:23:32
歴史的な事情(Cとの互換)と効率かと
355デフォルトの名無しさん:2008/08/10(日) 23:23:50
もしかしてC言語の構造体との互換性のため、組み込み型は自動では
初期化しないってことなのかな?
356デフォルトの名無しさん:2008/08/10(日) 23:24:59
かぶった…どうも
納得しました。
357デフォルトの名無しさん:2008/08/10(日) 23:30:07
>>355
未初期化だったものを初期化するように変更しても、行儀のいいソースなら動作は変わらないはずだから
互換性の問題というわけではないと思う。
C++の思想として効率的なコードがかける必要性があるからでは?
358デフォルトの名無しさん:2008/08/10(日) 23:32:09
う〜む、やはりそっちの理由ですか…
359デフォルトの名無しさん:2008/08/11(月) 09:50:38
テンプレートでクラスと同じ表記ができるようにするため
360デフォルトの名無しさん:2008/08/11(月) 09:53:47
続き
するためにint()という表記ができるようにしたが、デフォルトコンストラクタではないし、
わざわざCと違う動作をするように変更する必要がないためじゃないかな。
357の言うように効率面もあるだろうし。
361デフォルトの名無しさん:2008/08/11(月) 15:00:01
>>359
論点がずれてる
論点は

struct X {
int i, j;
X() : i() {}
};

で、i はゼロで初期化されるのに j は初期化されない理由
362デフォルトの名無しさん:2008/08/11(月) 15:16:53
jが初期化されるとなると、イニシャライザの実装とかめんどくないですか?
363デフォルトの名無しさん:2008/08/11(月) 17:47:24
357に書かれているように、Cとの互換よりも、効率でしょう

実際、性能重視の用途で勝手に初期化処理されて
CプログラムをC++に移植したら遅くなりましたではかなわない
例外ですら迷惑なのに
364デフォルトの名無しさん:2008/08/11(月) 19:23:11
>>361
論点がずれてたから360を書いた。
365デフォルトの名無しさん:2008/08/11(月) 22:01:28
すいません、糞社長にVBで書いたコードをCで書き直したら何%速くなるか
計算しろって言われたんですがどうすればいいですか?
10%だと書き直す必要はないからするな、50%速くなるなら書き直せ計算できるだろ!
って言われて困ってます
カメラの監視ソフトで画像を処理する感じのプログラムなんですが
366デフォルトの名無しさん:2008/08/11(月) 22:03:21
僕には無理ですでいいよもう
367デフォルトの名無しさん:2008/08/11(月) 22:04:26
>>366
おまえがやれ!って言ってやればいいですか?
368デフォルトの名無しさん:2008/08/11(月) 22:08:48
>>365
肝の部分を単純化したものをVBとCで書いて速度を比較する
で、「肝の部分を単純化して比較するとこうなりました」と報告すればいい
大して工数は掛からず嘘もなし
369デフォルトの名無しさん:2008/08/11(月) 22:09:27
>>368
すみません、C書いたことないんですが
370デフォルトの名無しさん:2008/08/11(月) 22:10:39
書き直しの工数を含めると10%以下になりますで良いだろ。
371デフォルトの名無しさん:2008/08/11(月) 22:11:35
>>369
じゃあ>>366
372デフォルトの名無しさん:2008/08/11(月) 22:12:29
>>369
>C書いたことないんですが

これは笑うことが期待されているのでしょうか?
373デフォルトの名無しさん:2008/08/11(月) 22:13:35
>>372
そんなこと聞かないでください!!
374デフォルトの名無しさん:2008/08/11(月) 22:48:43
とりあえず中間の30パーセントぐらいだったっていっときゃいーんだよwww
375デフォルトの名無しさん:2008/08/11(月) 22:56:02
>>369
C書いたことないんなら、書き直しても大して速くならないうえに
バグが50%増しになってオワルだけだろ
376デフォルトの名無しさん:2008/08/11(月) 22:57:48
長時間起動なんだろ?ついでにメモリリークも起こして使い物にならなくなるんじゃね
377デフォルトの名無しさん:2008/08/11(月) 23:25:19
C#だとむしろ遅くなるんでしょうか?
メモリリークはなくなりますが
378デフォルトの名無しさん:2008/08/11(月) 23:28:49
変換前と変換後の言語の両方でちゃんと書ける奴以外がやることじゃない
379デフォルトの名無しさん:2008/08/11(月) 23:49:06
みなさんどうもありがとうございました。ご意見を参考にさせていただいて
適当に回答しておきます。
話は変わりますが、その社長なんか変なんですよ。社員に内緒で、一番できる
技術者に占い(?)みたいなソフト作らせてるみたいなんですが
生年月日を入力するとオーラの量とかが測定できるみたいなんです。
どのようなアルゴリズムに基づいているのか本当に不思議です
あと、この前社長の机拭いてたら「ノストラダムスの大予言」って本が置いてあって
いくらなんでも季節外れでしょ。って思ったもんです。
その監視ソフトで業務中監視されてるみたいだし辞めた方がいいですかね?
380デフォルトの名無しさん:2008/08/12(火) 00:24:51
その社長に一生ついていくべきだYO
381デフォルトの名無しさん:2008/08/12(火) 03:58:26
そーいう話はプログラマ板でやれ
ここはプログラ「ム」板だ
382デフォルトの名無しさん:2008/08/12(火) 14:57:16
プログラマは凄腕の上級者になると Wizard と呼ばれるからな
間に占い師くらいいてもいいんじゃないかw
383デフォルトの名無しさん:2008/08/12(火) 15:17:26
クラスのメソッドを名前で呼び出したくて以下を作ってみましたが、
Type2Typeで型毎にわけてif文を構築するのが面倒です
どう実装すれば、この型毎にわけずに、以下の実装のようにgetだけで値をとれるようになるのか
教えてもらえないですか。
template <typename T>
struct Type2Type { typedef T OriginalType; };
class hoge {
private:
  int _int1v; int _int2v; char _charv; long _longv;
public:
  hoge() : _int1v(0), _int2v(0), _charv(0), _longv(0) {}
  void getInt1(int& v) {v = _int1v;};  void getInt2(int& v) {v = _int2v;};
  void getChar(char& v) {v = _charv;};  void getLong(long& v) {v = _longv;};
  template <typename T> void get(const string& name, T& t, Type2Type<int>) {
    if (name.compare("getInt1") == 0) getInt1(t);
    else if (name.compare("getInt2") == 0) getInt2(t);
  }
  template <typename T> void get(const string& name, T& t, Type2Type<char>) {
    if (name.compare("getChar") == 0) getChar(t);
  }
  template <typename T> void get(const string& name, T& t, Type2Type<long>) {
    if (name.compare("getLong") == 0) getLong(t);
  }
  template <typename T> void get(const string& name, T& t) {
    get(name, t, Type2Type<T>());
  }
};
void main() {
  hoge h; int int1v; int int2v; char charv; long longv;
  h.get("getInt1", int1v); h.get("getInt2", int2v);
  h.get("getChar", charv); h.get("getLong", longv);
}
384383:2008/08/12(火) 15:22:57
ほんとはこんなかんじで1つのメソッドにまとめたいけど、コンパイルエラーになります
  template <typename T>
  void get(const string& name, T& t) {
    if (name.compare("getInt1") == 0) getInt1(t);
    else if (name.compare("getInt2") == 0) getInt2(t);
    else if (name.compare("getChar") == 0) getChar(t);
    else if (name.compare("getLong") == 0) getLong(t);
  }

'hoge::getChar' : 1 番目の引数を 'int' から 'char &' に変換できません。

上記のエラーがいろいろでますが、コンパイラがif文をみてくれるわけでないので、
型が一致しないのはそうだと思い、Type2Typeで分けてみたけど、
型毎にメソッドを分けないといけないのが面倒です。
385デフォルトの名無しさん:2008/08/12(火) 15:58:45
>>384
こういうのでどう
template <typename T> void getInt1(T& v) { v = static_cast<T>(_int1v); };
template <typename T> void getInt2(T& v) { v = static_cast<T>(_int2v); };
template <typename T> void getChar(T& v) { v = static_cast<T>(_charv); };
template <typename T> void getLong(T& v) { v = static_cast<T>(_longv); };
386デフォルトの名無しさん:2008/08/12(火) 16:08:14
こうとかな
template<class T>
T get(std::string name)
{
if (name.compare("i1") == 0) return static_cast<T>(i1);
else if (name.compare("i2") == 0) return static_cast<T>(i2);
else if (name.compare("f1") == 0) return static_cast<T>(f1);
else if (name.compare("f2") == 0) return static_cast<T>(f2);
return T();
}
まあ同じことだが
387デフォルトの名無しさん:2008/08/12(火) 16:30:41
実装はできたとして、設計上はそれでいいのか?
どういう使い方するのかよく分からないけどさ
388383:2008/08/12(火) 16:36:33
>>385, 386
おしえてくれてありがとうございます。例が悪かったです。すいません。
この方法って、structか、classをメンバにしたときとかにしたとき、コンパイルエラーになってしまいます。

struct XXX {};

template <typename T> void getString(T& v) { v = static_cast<T>(_strv); };
template <typename T> void getXXX(T& v) { v = static_cast<T>(_xxxv); };
389383:2008/08/12(火) 16:40:26
>>387
はい、xml等、なんらかの定義からC++のクラスをツールで作成して使おうと思っています。
その時に、名前でgetterとsetterを実装しておきたいという感じです。
なので、問題ないと思っています。
390デフォルトの名無しさん:2008/08/12(火) 16:43:41
お勧めしないが最終奥儀

if (name.compare("i1") == 0) v = *((T*)(&i1));
else if (name.compare("i2") == 0) v = *((T*)(&i2));
else if (name.compare("f1") == 0) v = *((T*)(&f1));
else if (name.compare("f2") == 0) v = *((T*)(&f2));

これでなんにでも変換できるが、get<int>("f1")とかでもエラーがでないのが問題
もっとスマートな方法ないかな・・・
391デフォルトの名無しさん:2008/08/12(火) 16:45:35
boost::anyみたいなことやるしかないだろう
それか全部stringにしてboost::lexical_cast
392デフォルトの名無しさん:2008/08/12(火) 16:50:30
boost::serializeで一度調べてみると幸せになれるかも
393383:2008/08/12(火) 16:54:37
>>391
どーも、どーも、boost::anyを考えた時は、void get(const string& name, any v) にしてみたんですが、
値をどうやって返してもらうんだ?、で、やめました。
内部クラスのholderのメンバが、ValueType held と値になっているから、値渡しでは無理なのかなぁと思っています。
>>392
ありがとう。boost::serializeにちょっくら行ってきます。
394383:2008/08/12(火) 17:49:58
>>392
まずはBoostC++Libraries第2版のserialization 4.4〜4.5を読んでみたけど、
幸せになれなかったです。どの辺を考慮してみるべきか教えてもらえないですか。
395383:2008/08/12(火) 19:19:52
>>391 anyでできました レスクレタカタアリガトウ CAnyハ自分用デス。
struct xxx {
  xxx() : _strval("xxx") {}
  string _strval;
};
class hoge {
private:
  int _int1v; int _int2v; char _charv; long _longv; string _strv; xxx _xxxv;
public:
  hoge() : _int1v(0x01), _int2v(0x02), _charv(0x03), _longv(0x04), _strv("boge"), _xxxv() {}
  void getInt1(int& v) {v = _int1v;};  void getInt2(int& v) {v = _int2v;};
  void getChar(char& v) {v = _charv;};  void getLong(long& v) {v = _longv;};
  void getString(string& v) {v = _strv;};  void getXXX(xxx& v) {v = _xxxv;};
  void getInt1(CAny& v) {v.Swap(CAny(_int1v));};  void getInt2(CAny& v) {v.Swap(CAny(_int2v));};
  void getChar(CAny& v) {v.Swap(CAny(_charv));};  void getLong(CAny& v) {v.Swap(CAny(_longv));};
  void getString(CAny& v) {v.Swap(CAny(_strv));};  void getXXX(CAny& v) {v.Swap(CAny(_xxxv));};
  template <typename T> void get(const string& name, T& t) {
    if (name.compare("getInt1") == 0) {CAny a(t);getInt1(a);t = any_cast<T>(a);}
    else if (name.compare("getInt2") == 0) {CAny a(t);getInt2(a);t = any_cast<T>(a);}
    else if (name.compare("getChar") == 0) {CAny a(t);getChar(a);t = any_cast<T>(a);}
    else if (name.compare("getLong") == 0) {CAny a(t);getLong(a);t = any_cast<T>(a);}
    else if (name.compare("getString") == 0) {CAny a(t);getString(a);t = any_cast<T>(a);}
    else if (name.compare("getXXX") == 0) {CAny a(t);getXXX(a);t = any_cast<T>(a);}
  }
};

hoge h; int int1v; int int2v; char charv; long longv; string aaav; xxx xxxv;
h.get("getInt1", int1v); h.get("getInt2", int2v);
h.get("getChar", charv); h.get("getLong", longv);
h.get("getString", aaav); h.get("getXXX", xxxv);
396デフォルトの名無しさん:2008/08/13(水) 09:09:23
多次元配列クラス作ってたんだけどoperator[](読み方分からん)の実装が悩む。
boostと違って、次元数も要素数も自由自在だから、ある程度再帰的な機構が必要なんだよね。

とりあえず配列クラスと要素クラスを作ってそれぞれに要素クラスを返すoperator[]と
配列タイプTの参照を返すキャスト演算子を作ってできたんだけど、printfみたいな
引数の型が分からない場合にわざわざキャストしてあげないといけなくて
めんどいんだけど何とかならんかね
397デフォルトの名無しさん:2008/08/13(水) 09:13:37
>>396
普通stream。
398デフォルトの名無しさん:2008/08/13(水) 10:06:49
streamやってみたけど〜と〜が曖昧みたいなこといわれて通らんかった。

あきらめてT* operator->を定義して妥協した。
399デフォルトの名無しさん:2008/08/13(水) 10:53:36
例外発生時にログを残したいんだが、throw履歴みたいのって参照できないの?
最悪デバッグ時でもいいんだが、そっちはスレチか・・・
ちなみにVisualStudio2008
400デフォルトの名無しさん:2008/08/13(水) 11:05:38
>>399
判然としないがあれか、例外発生時にどんな関数がどんな順番で呼ばれてたわかるようなやつか?

本当に『わかればいい』ならDebugビルドで例外をcatchせずにmainの外まで放り出せば
デバッガは例外throw時点まで巻き戻して止まるからデバッガの呼び出し履歴ウィンドウを見ればいい。

プログラム側から呼び出し履歴を見る方法があるのかは知らん。 少なくとも言語仕様ではない。
401デフォルトの名無しさん:2008/08/13(水) 11:20:18
レスさんくす!
そういうこと。本当はリリース版でも正確なログを残したいんだよね^^;
デバッグ時に例外をキャッチしない方法があるか調べてみますわ
402デフォルトの名無しさん:2008/08/13(水) 11:27:58
自分が投げる例外だけ記録すればいいなら例外クラスのコンストラクタにでもログ記録用のコード書けば?
403デフォルトの名無しさん:2008/08/13(水) 11:29:48
>>398
struct Hage {
  int n;
  Hage():n(){}
  Hage(int an):n(an){}
};
std::ostream& operator<<(std::ostream& ost, const Hage& o){
  ost << o.n;
  return ost;
}
std::istream& operator>>(std::istream& ist, Hage& o){
  int n;
  ist >> n;
  o = Hage(n);
  return ist;
}
void f(){
  Hage a(10),b;
  std::stringstream ss;
  ss << a;
  ss >> b;
  std::cout << b << std::endl; // "10"
}
404デフォルトの名無しさん:2008/08/13(水) 11:31:28
bad_allocとかbad_castとかの発生場所も知りたいんだよね^^;
最悪リリース時は自分のログだけでも残すようにしてみるよ
405デフォルトの名無しさん:2008/08/13(水) 16:50:17
>>403ありがとう。でも問題はそれだけじゃないから。、やっぱりアロー演算子で何とかするぜ。
ていうか、見てくれる人がいるならソース上げたいんだけど、ダメだろうか?
406デフォルトの名無しさん:2008/08/13(水) 17:08:05
良いんじゃない?
ソース上げるなら↓の1にあるロダが良いと思う
http://pc11.2ch.net/test/read.cgi/tech/1218023777/1
407405:2008/08/13(水) 19:07:33
main.cpp
ttp://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/7611.txt

Aray.hpp
ttp://kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/7612.txt

こんな感じです。もっとお勧めの実装があればだれかヨロ
408デフォルトの名無しさん:2008/08/13(水) 22:04:12
STLを勉強していて思ったのだが、ずいぶんと関数名や引数に一貫性が
ないところが見受けられるよな。範囲に対して範囲で検索するアルゴリズムの
場合で言うと、最初の範囲を検索するのsearchに対して、最後の範囲を
検索するのがfind_endとか。まぁごっちゃに開発したのを統合したから
こうなったんだと思うが、こういうのって一度標準として決まっちゃうと
改善されないのかね。互換性は失うけど、後々までこういう不手際が
残るのも問題だと思うが。そのへんて、C++0xで整理されないのかな。
409デフォルトの名無しさん:2008/08/13(水) 22:15:24
creat頑張れ。
410デフォルトの名無しさん:2008/08/14(木) 00:03:01
>>408
我々から見ると単に一貫性を欠いてるだけに見えるけど
英語ネイティブな人たちにとってはあれで自然なのかも
411デフォルトの名無しさん:2008/08/14(木) 02:43:43
>>408
find_end() については SGI のページにはっきり "misnamed" と書いてある。
http://www.sgi.com/tech/stl/find_end.html
412デフォルトの名無しさん:2008/08/14(木) 09:36:40
なんじゃそりゃ・・・
413デフォルトの名無しさん:2008/08/14(木) 10:12:03
typedef void (*set)(int);
class AAA {
public:
void setHoge(int a){};
};
class BBB {
public:
void setFugo(int a){};
};
set hoge = &AAA::setHoge;
set fugo = &BBB:setFugo;
↑ この2行がエラーになります。
intの引数を取る関数ポインタとしてAAAとBBBのsetHogeとsetFugoを扱いたいのですが、どうすればいいでしょうか。
AAAとBBBは親子関係や親クラスが一緒とかないです。共通の親クラスの関数をオーバーライドしないとできないと思っています。
typedef void (OYA::*set)(int);
class OYA {
public:
virtual void setOYA(int g) = 0;
};
class AAA : public OYA {
public:
void setOYA(int g) {}
};
class BBB : public OYA {
publc:
void setOYA(int g){}
};
set hoge = &AAA::setOYA;
set fugo = &BBB:setOYA;
↑ これだといけるけど、親クラスを作って名前を合わせないといけない。
414デフォルトの名無しさん:2008/08/14(木) 10:15:12
class AAA {
public:
static void setHoge(int a){};
};
class BBB {
public:
static void setFugo(int a){};
};
415デフォルトの名無しさん:2008/08/14(木) 10:15:38
search_nの二項叙述関数を受け取る形式

search_n(beg, end, count, value, binary_predicate)

これも、ミスらしいね。二項叙述関数受け取るくせに、その叙述関数の2番目の
引数はvalueで固定。この場合、STLの一貫性に従うなら単項叙述関数を受け取るように
して、二項にしたい場合はbind2dなどを使うようにするべきだった。
これなら単項でも二項でも二項のどちらの引数としてでも働く。
416デフォルトの名無しさん:2008/08/14(木) 10:22:21
>>414
ごめん、クラス内でインスタンス毎の変数をさわりたいから、staticはだめなんす。
417デフォルトの名無しさん:2008/08/14(木) 10:23:38
親クラスを作って名前を合わせる以外に方法はない
418デフォルトの名無しさん:2008/08/14(木) 10:45:32
>>416
そのインスタンスはset hoge = …の時点で分かってるの?
それとも呼び出すまで分からない?
前者ならboost::bind+boost::functionでなんとかなる
419デフォルトの名無しさん:2008/08/14(木) 12:39:50
>>417
残念。ありがとう。
>>418
set hoge=・・・の時点ですでにわかっています。関連のないクラスの引数、戻り値が一緒なだけのメソッドを、
どこかに保存しておいてあとでまとめて呼び出したいんです。
というわけで、boost::bindとboost::functionを見てみます。ありがとう。
420デフォルトの名無しさん:2008/08/14(木) 13:35:07
#include <iostream>
using namespace std;
//関数宣言
float *lineIntersect(float *L1Point, float L1Slope, float *L2Point, float L2Slope);
int main()
{
float tmp[2];
float sl1 = 1/2;
float sl2 = 1/4;
float pt1[2] = {10, 20};
float pt2[2] = {20, 10};

*tmp = *lineIntersect(pt1, sl1, pt2, sl2);
     cout << tmp[0] << "___" << tmp[1];

return 0;
}
float *lineIntersect(float *L1Point, float L1Slope, float *L2Point, float L2Slope) {
float ans[2] = {0, 0};

ans[0] = (L1Slope * L1Point[0] - L2Slope * L2Point[0] +
L2Point[1] - L1Point[1]) / (L1Slope - L2Slope);
ans[1] = L1Slope(ans[0] - L1Point[0]) + L1Point[1];

return ans;
}
cpp(26) : error C2064: 1 引数を取り込む関数には評価されません。
cpp(28) : warning C4172: ローカル変数またはテンポラリのアドレスを返します
2つの直線が与えられたときその交点を返す関数を記述してみたのですがエラーが2個出てなおせません;;
誰か御助けお願いします
421デフォルトの名無しさん:2008/08/14(木) 13:39:42
まずエラーと警告をよく読んで意味を考えてみよう。
422デフォルトの名無しさん:2008/08/14(木) 13:49:59
>>420
・26行目のエラーはケアレスミス。このくらい、自分で見つけろ。
・28行目の警告は初心者にありがちなミス。配列を返すことはできないので、2変数返すには工夫が必要。
・そもそも、配列についてまともに理解できていない。勉強しなおすことをお勧め。
・実数を扱うなら、特にそうする理由がないならfloatではなくdoubleを使うべき。
・1/2は整数演算しか行なわれないので、0になる。
以下省略。

出直すなら、初心者スレへどうぞ。
423デフォルトの名無しさん:2008/08/14(木) 14:06:25
419です。
>>417, 418
結局、関数ポインタを内包するクラスをつくって、templateで解決しました。
boost::bindとboost::functionを見てクラスにすればいいのか、という感じで解決しました。ありがとうございます。
424デフォルトの名無しさん:2008/08/14(木) 14:27:34
425デフォルトの名無しさん:2008/08/14(木) 14:41:58
419です。教えてくれた方、ありがとうございます。こんなかんじでつくりました。
最終形はCCCはvectorに入れたかったので、
boost::anyみたいに内部クラスでテンプレートを使うようにして入れるようにしました。
template <typename T>
class CCC {
public:
  typedef void (T::* set)(int);
private:
  T& _t;
  set _func;
public:
  CCC(set func, T& t) : _func(func), _t(t) {}
  void invoke(int v) {(_t.*_func)(v);}
};
class AAA {
public:
  void setHoge(int a){printf("AAA %d\n", a);}
};
class BBB {
public:
  void setFugo(int a){printf("BBB %d\n", a);}
};
void main() {
AAA aaa; BBB bbb;
CCC<AAA> cccA(&AAA::setHoge, aaa); CCC<BBB> cccB(&BBB::setFugo, bbb);
cccA.invoke(1); cccB.invoke(2);
}
426デフォルトの名無しさん:2008/08/14(木) 22:35:29
>>407は何かある人は居ないですか・・・?
427デフォルトの名無しさん:2008/08/14(木) 22:40:47
swapを実装しといた方が便利だし実装も楽だよとか?
428デフォルトの名無しさん:2008/08/14(木) 23:12:45
確かにそうですね。copyとかも付けます。
特になさそうなので、ありがとうございました。
429デフォルトの名無しさん:2008/08/19(火) 13:21:43
単品でnewしたものをdeleteで開放するのはわかるんですけが、例えば
int *p = new int[10];
delete [] p;
のような場合、ソース上だとdeleteするときサイズがわからないけど配列分
開放されているのですよね?ということは実際にはどこかにサイズが保持
されているってことなんでしょうか?
それなら[]無しのdeleteでもきちんと消すことが出来るんじゃないかとか考え
ていたんですけど、仕様云々なんだろうか。
 興味本位の質問ですが、アセンブラわからないのでお手柔らかに教えて
いただきたい。

430デフォルトの名無しさん:2008/08/19(火) 13:25:03
仕様
431デフォルトの名無しさん:2008/08/19(火) 13:40:30
>>429
その考えでいくと、単品の new でもサイズが 1 であることをどこかに保存しないといけない
ことになる。これはゼロオーバーヘッドの原則に反する。だから仕様。

区別したくないんだったら常に new int[1] として全部 delete [] で解放すればいいんじゃね?

まじめな話、動的配列には常に std::vector や boost あるいは tr1 の array を使うのがおすすめ。
これで自分で使う new/delete は単品だけになる。さらに各種スマートポインタを使えば delete を
直接使うことも無くなる。
432デフォルトの名無しさん:2008/08/19(火) 15:12:46
よく継承するクラスはデストラクタをvirtualにしろってあるけど、
基底クラスを直接deleteしない場合は問題ないよな?
効率的にあんまりvirtual使いたくないんだ。

あと、基底クラスでvirtualな関数を、派生クラスで
virtual外すことに意味ってある?結局virtualになる気がするが・・・
433デフォルトの名無しさん:2008/08/19(火) 15:26:53
基底クラスを直接deleteしないなら、基底クラスのデストラクタはprotectedにしとくといいかもしんない
virtualは、書いても書かなくても同じなら、わざわざ書かなくていいんじゃない
434デフォルトの名無しさん:2008/08/19(火) 15:36:36
書いても書かなくても同じなのかがよく分からん。リークしなけりゃいいが
デストラクタをpublic以外に置くのはいいかもな
435デフォルトの名無しさん:2008/08/19(火) 15:51:22
基底の関数がvirtualなら、そのクラスの全派生クラスの、同名の関数は
virtualと書かなくても仮想関数になる(仮想関数テーブルを上書きし、そこから呼ばれる)。
もちデストラクタも。これは単にオーバーライドのルール。

あとデストラクタをprotectedにするのは、(わかってそうだけど一応)基底クラスのポインタを
deleteするときに外部から基底クラスのデストラクタを呼べなくする。
つまり派生クラスのpublicなデストラクタを外から呼び、派生が基底のデストラクタを
呼ぶことでのみdeleteできる(=基底のポインタからはdelete不可)。

んだが、基底のデストラクタをprivateにしちゃうと、↑と似た理由で
継承も禁止しちゃうので注意。継承禁止の意味で使えるけど。
436デフォルトの名無しさん:2008/08/19(火) 16:00:09
了解!サンクス!
437429:2008/08/19(火) 16:00:47
う〜ん、仕様ということですか。ありがとう。
例えでnew[]を[]無しのdeleteと書いたけど、もしdelete[]でどこかの
サイズを参照して開放しているならばポインタから確保されたサイズ
を得る方法があるんじゃないかと思ったまでです。
438デフォルトの名無しさん:2008/08/19(火) 16:04:58
>>437
もちろんサイズは保持しているよ。
[] 無しでも領域は開放されるけど、個々のデストラクタは呼ばれない。
439デフォルトの名無しさん:2008/08/19(火) 16:10:46
先頭アドレスのひとつ前に保存してる実装があると聞いた事あるけど
普通は自分じゃ弄ること無いからな。
440デフォルトの名無しさん:2008/08/19(火) 16:22:26
コンパイラ依存だった気がする
441デフォルトの名無しさん:2008/08/19(火) 18:50:22
((int*)ptr)[-1] だっけ?VCならいけるんじゃない?
442デフォルトの名無しさん:2008/08/19(火) 19:08:19
いや、デストラクタの無い int だとそこには入ってないと思うよ。
自分でクラス定義してそれでやってみるとわかる。
443デフォルトの名無しさん:2008/08/19(火) 19:28:09
あー、そうじゃなくてptrはデストラクタのあるクラスへのポインタね。
要素数は確かintサイズだからこうなるよね?違ったっけ?
444デフォルトの名無しさん:2008/08/19(火) 20:31:06
445デフォルトの名無しさん:2008/08/19(火) 20:32:59
>>437
だから []なしの delete が要素数を参照するようにすると
常に、[]なしのnewしたときにも要素数が必要になるということを >>431 が言っている
446デフォルトの名無しさん:2008/08/20(水) 10:00:08
ここで質問していいのか分かりませんが・・・
プリコンパイル済みヘッダーにテンプレートやインラインが含まれている場合の
処理ってどうなるんでしょう。中間ファイル作ってリンクってできないですよね?
447デフォルトの名無しさん:2008/08/20(水) 10:04:41
コンパイルの途中の状態をそのまま保存してるんだけど。
448デフォルトの名無しさん:2008/08/21(木) 13:34:20
それぞれのソースファイルで関連のないヘッダーはインクルードしない方がいいと思うんだけど、
プリコンパイル用ヘッダーの中に何でもかんでも放り込むのはやっぱり良くないのかね?
449デフォルトの名無しさん:2008/08/21(木) 14:24:08
>>448
名前汚染が怖くないなら(ちゃんとnamespaceで囲ってあったり冗長な名前を使っているなら)、
何でもかんでも放り込んでおくのはそんなに悪い考えというわけでもないと思う。
どうせ名前の数が増えたってコンパイラが名前の探索に必要な時間は高々O(logn)なんだし。

例えばboostとSTLのよく使うヘッダーをどばーっとPCHでインクルードしておいて、
(可読性とか念のために)本当に使うところでも#includeを書いておけば、インクルードガードのおかげで
結構速くコンパイルできるようになるんじゃないかな。
450デフォルトの名無しさん:2008/08/21(木) 14:47:05
>>448
何でも入れるヘッダは良くない。

>>449
ひとつのソースのコンパイルにかかる時間は問題じゃないと思う。
再コンパイルの必要なソースがいくつ発生するかってところが問題でしょ。
451デフォルトの名無しさん:2008/08/21(木) 15:20:31
>再コンパイルの必要な
プリコンパイルヘッダの話でしょ?
標準ライブラリみたいな通常変わらないヘッダを入れるものだよ。
自分らが書くヘッダを入れちゃ駄目だから、再コンパイルについては逆に大丈夫。

むしろプリコンパイルヘッダに都度インクルード文を追加していくのも間違い。
その都度プリコンパイルヘッダ使ってるソース全部再コンパイル対象になるから。
先に使いそうなのを入れておく。
452デフォルトの名無しさん:2008/08/21(木) 15:37:30
>>449
本当に使うところでインクルードするならpchでインクルードしなくていいと思うんだが。
本当に使うところでインクルードしなくても良くなるから中途半端でわ?

ソースファイルの独立性が低くなるから、自分はpchでインクルードしない。
やるとしても開発時のみにする。
453451 (≠449):2008/08/21(木) 15:45:40
>やるとしても開発時のみに
超同意。
コンパイル時間短縮だけが目的だしね。
俺の場合、一通り作り終わったらコメントアウトしてる。
454デフォルトの名無しさん:2008/08/21(木) 15:48:18
pch使うとビルド時間が逆に短縮できる場合もあるのでは?

ライブラリAを複数のソースからインクルードするとそれぞれのソースで
展開されて時間がかかる場合にpchつかうんじゃないの?
455デフォルトの名無しさん:2008/08/21(木) 15:50:24
プリコンパイルドヘッダのインクルードをコメントアウトしても
コンパイルできるように書いてはいるが、実際に外したことはない。
456デフォルトの名無しさん:2008/08/21(木) 15:51:28
boostなんかを使うときはプリコンパイルの恩恵がよく分かる
457デフォルトの名無しさん:2008/08/21(木) 15:52:33
ちょっと前まで、ディスクの空きがきつくなってくると *.pchをごっそり消してしのいだもんだw
458デフォルトの名無しさん:2008/08/21(木) 15:53:52
そもそもコンパイルと言ってもmakeとか使って、変更された部分だけやるんだから、
プリコンパイル済みによるありがた味なんてそんなに出ない。
全体に影響が出るような変更はほいほい行うもんでもない。
てか、そんなに大きなプログラム作ってやるもんかっ
うえっ、、、うえぅ、、、
作れないんじゃないぞっ
作らないんだからな
うぇ、、うぇ、、
459デフォルトの名無しさん:2008/08/21(木) 15:54:53
>>457
あるあるw
460452:2008/08/21(木) 17:36:45
452の前半は変なこと書いてたな。ごめん。
461452:2008/08/21(木) 17:48:18
>>449
>例えばboostとSTLのよく使うヘッダーをどばーっとPCHでインクルードしておいて、
>(可読性とか念のために)本当に使うところでも#includeを書いておけば、インクルードガードのおかげで
>結構速くコンパイルできるようになるんじゃないかな。

ちょうどboost使ってるソースがあったのでやってみたら、体感できる効果があった。
これからは開発時はそうしようっと。
462デフォルトの名無しさん:2008/08/21(木) 19:55:14
gccなら.hと同じディレクトリに.gch置いておけば、
.hの代わりにプリコンパイル済みの方を優先して読み込んでくれてる(気がする。)
463デフォルトの名無しさん:2008/08/22(金) 20:09:36
unsigned int i = 0;
int j = i - 1;
このようなコードがあったとき,jが-1になることは規格で保証されていますか?
464デフォルトの名無しさん:2008/08/22(金) 20:22:40
int j = static_cast<int>(i) - 1;
int j = satatic_cast<int>(i - 1);
465デフォルトの名無しさん:2008/08/23(土) 00:03:01
>>463
負数の表現方法が決まってなかった気がするのでだめだと思う。
つかその前に符号なし整数が0より小さくなった時点で処理系定義かと。
466デフォルトの名無しさん:2008/08/23(土) 00:07:49
符号なし整数はどんなに頑張っても0より小さくなることができないんだが
467デフォルトの名無しさん:2008/08/23(土) 00:17:45
>>463
i - 1 が UINT_MAX になることは保証されているけど、それを int に入れようとしても
ほぼ確実に INT_MAX より大きいんで、値は処理系定義となってしまう。
468デフォルトの名無しさん:2008/08/23(土) 00:21:03
>>463
i - 1 は (unsigned int) - (signed int) なので、
(unsigned int) - (unsigned int) に変換してから計算することになっている。
したがって、この式の型は (unsigned int) で、0u - 1u = MAX_UINT

結果として、MAX_UINTは多くの処理系で(signed int)で表せないので、
代入される値は処理系定義。
469デフォルトの名無しさん:2008/08/23(土) 00:59:59
0u -1uがUINT_MAXになるのって規格書のどの辺に書いてあるの?
470デフォルトの名無しさん:2008/08/23(土) 01:07:12
1の補数を使ってる処理系もあるから普通に考えたらアウトだろ
471デフォルトの名無しさん:2008/08/23(土) 01:08:24
>>469
これかな?

3.9.1 Fundamental types p4
> Unsigned integers, declared unsigned, shall obey the laws of arithmetic modulo 2n where n is the number
> of bits in the value representation of that particular size of integer.41)

> 41) This implies that unsigned arithmetic does not overflow because a result that cannot be represented
> by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest
> value that can be represented by the resulting unsigned integer type.
472デフォルトの名無しさん:2008/08/23(土) 01:36:22
>>470
unsigned の話だよ。
473デフォルトの名無しさん:2008/08/23(土) 05:58:08
463は代入のとき左辺の型に全部合わせてくれると思ってるんじゃないかな。
演算子の優先順位から、
int j = i - 1は、まず先にi - 1が先に評価されるわけで、jは関係しない。
減算演算子はその左の項から評価されるから、iの型に1が暗黙変換されて
当然その結果もunsignedになる。でその値がjの型にキャストされてjに代入される。
474デフォルトの名無しさん:2008/08/23(土) 09:14:24
>>473
>>減算演算子はその左の項から評価されるから、iの型に1が暗黙変換されて
ちょっと違うんじゃないかな。
柴田ボウヨウの本によると、片方のオペランドがunsignedなら他方をunsignedにすると書いてある。
右か左かは関係ないんじゃないかな。
475デフォルトの名無しさん:2008/08/23(土) 10:15:22
おまえら汎整数拡張は一応覚えておかないとたまにハマるぞ
476デフォルトの名無しさん:2008/08/23(土) 13:24:41
unspecified behavior
477デフォルトの名無しさん:2008/08/23(土) 13:30:51
絶対値が大きい奴に合わせて、char系だけ例外だと誰かがいってたようなきがするけど思い出せない
478デフォルトの名無しさん:2008/08/23(土) 13:35:49
どこの気違いだよ、そんなこと言ってんのは
479デフォルトの名無しさん:2008/08/23(土) 14:42:17
C99でまた微妙にルールが変わってるんだよな
ほんとややこしい
480デフォルトの名無しさん:2008/08/23(土) 15:55:14
C99はとりあえずC++では考えなくていいだろ
481デフォルトの名無しさん:2008/08/23(土) 20:30:23
>>478
まさに汎整数拡張では?
short == intの環境なら、確かにchar系だけが対象になる。
482デフォルトの名無しさん:2008/08/23(土) 21:57:57
日本語でおk
483デフォルトの名無しさん:2008/08/23(土) 22:50:52
VB系しか経験ないんですがC++でいい本ありますか?
本屋にはロベールのC++教室とか独習C++とかありました。
そこそこ難度高くても1000ページ以内で無駄に紙面を使ってない本がいいです
MFCとかWinAPIまではあまり触れてなくても構いません
VB.NETである程度オブジェクト指向は理解してるつもりです
484デフォルトの名無しさん:2008/08/23(土) 22:54:31
>>483
つ仕様書
485デフォルトの名無しさん:2008/08/23(土) 22:59:15
最近C/C++の基本的な部分をやっと習得し終えました。
(といっても独習C/C++知識を一通り理解したレベルですが・・)
知識が不十分なところがあり、効率は遅々としたものになるのはわかっているのですが
C/C++によるWindowsアプリに挑戦したいと思っています。

そこで、Win32APIかMFCどちらかにまず挑戦したいと考えているのですが、どちらがお勧めでしょうか?
また、それぞれの比較・メリットデメリットなど教えてもらえるとうれしいです

よろしくお願いします
486デフォルトの名無しさん:2008/08/23(土) 23:46:16
>>485
つMSDN
487デフォルトの名無しさん:2008/08/23(土) 23:46:34
>485
Windows 特定だからこっちのスレの方が適してんじゃね?

【初心者歓迎】C/C++室 Ver.58【環境依存OK】
http://pc11.2ch.net/test/read.cgi/tech/1218023777/

MFC は使ったこと無い俺が適当に答えてみるとこんな感じか?

Win32API: 低レベル、面倒
MFC: ごてごて、割と楽?

あと、WTL(Windows Template Library)ってのもあって結構良さそげだけど、どれも将来性に不安が残るところ。
488デフォルトの名無しさん:2008/08/24(日) 18:18:55
> Win32API: 低レベル、面倒

あれが面倒ね・・・
C++ 使いがそんなこと言ってるのは技量不足に他ならない

# MFC はいわばクラシック C++
489デフォルトの名無しさん:2008/08/24(日) 19:12:13
IT土方乙
490デフォルトの名無しさん:2008/08/25(月) 02:18:54
>>485
どういう目的でC++やるのかによるかもしれないが、通常なら
断然WIN32APIからやった方がいいと思うよ。
MFCは当然API使っているから、後でMFC使う時も理解が深まる。
っていうか、API知らないとMFCでトラブった時に自力で解決できない。

MFCを使う場合は、VSがメソッドの追加とかをサポートしてくれる
楽な機能があるから、いい加減にソフト作るときは楽。でもそれなら
C#とか使えばいいし、正直いまさらやることもない気がする。

WTLはAPIの薄いラッパーみたいな感じなので、結構使いやすい。
APIがある程度わかってきたら、これで楽するといいかも。
491デフォルトの名無しさん:2008/08/25(月) 20:33:26
X* p = 0;
delete p;
このコードは合法ですか?
つまりdeleteに空ポインタを渡してもOKですか?
492デフォルトの名無しさん:2008/08/25(月) 20:37:21
問題ない。
493491:2008/08/25(月) 20:42:06
>>492
サンクスです。
494デフォルトの名無しさん:2008/08/25(月) 21:08:28
でも0を使うのはお勧めしない。
C++0xにはnullptrも入ることだし。
495デフォルトの名無しさん:2008/08/25(月) 21:10:51
ドラフトだけ読んで言ってもらっても。
ISO/IEC14882:2003では 0 を推奨しているので 0 でいい。
496デフォルトの名無しさん:2008/08/25(月) 21:23:38
>>494
じゃぁなに使えばいいですか?
497デフォルトの名無しさん:2008/08/25(月) 21:26:45
>>496
当面ゼロでいい。
498デフォルトの名無しさん:2008/08/25(月) 23:28:58
私は 0 推奨に一票
499デフォルトの名無しさん:2008/08/26(火) 00:21:42
0非推奨の根拠って0を代入した整数型の変数をポインタに代入してもヌルポインタになる保証がないからだっけ?
500デフォルトの名無しさん:2008/08/26(火) 00:30:34
ポインタやfloatのクリアにmemset使うなってだけのこと
501デフォルトの名無しさん:2008/08/26(火) 00:34:15
>>499
誰が0を非推奨にしてる?
502デフォルトの名無しさん:2008/08/26(火) 00:42:46
>>494のアホ一人
503デフォルトの名無しさん:2008/08/26(火) 06:05:29
>>499
そんなことやってコンパイル通る?
もちろんreinterpret_cast使ったら通るだろうけど

C++0xで0が推奨されない理由としては、ポインタではなく数値と解釈されうるせいで、
オーバーロードで自分の予想に反する関数が呼ばれたり、
変な型が型変換にかかってポインタとして扱われたり、
そういう理由だったからだと思う
もっとも、一般には現行のC++でそれを防ぐ術はないけど

もちろん、(void*)0をNULLと定義して(一般のC++ではNULL=0)、
NULL代入するたびにキャストかますのであれば防げるけどね
504デフォルトの名無しさん:2008/08/26(火) 06:07:10
なんでC++じゃNULLを(void *)0って定義されてないか知ってる?
505503:2008/08/26(火) 06:12:20
>>504
俺に訊いてんの?そりゃ知ってるけど
506デフォルトの名無しさん:2008/08/26(火) 10:32:54
>>503
ここはC++0xスレじゃありませんよ
507デフォルトの名無しさん:2008/08/26(火) 10:48:07
typedefについて質問です

typedef int myint;と宣言した場合、
int a;
myint b;
a=b;

等と行った場合、intにintを代入するよりオーバーヘッドはあるのでしょうか
508デフォルトの名無しさん:2008/08/26(火) 11:33:49
オーバーヘッドはありません。typedefは単なる別名を定義する修飾子であり、myintとintは全く同じであります。
509デフォルトの名無しさん:2008/08/26(火) 11:52:52
ありがとうございます!
これで心おきなくtypedefできます
510デフォルトの名無しさん:2008/08/26(火) 12:40:11
いろいろベンチマークとってたら
組み込み型変数はコンストラクタの初期化リストで初期化するより
代入の方が高速になったんだけど・・・これって普通?
511503:2008/08/26(火) 12:52:44
>>506
C++0xで0が非推奨になる理由=C++03で0を使うときに注意すべき事項だろう
というか最初にC++0xの話題振ったのは>>494だけど
512デフォルトの名無しさん:2008/08/26(火) 13:43:08
>>510
そんなことになる理由はあんまり考えられないなぁ。
テストしたコンパイラ、とかベンチマークのコードとか挙げてもらわないとなんとも。
513デフォルトの名無しさん:2008/08/26(火) 14:58:16
長くて悪い

呼び側
int i=100000000;
int c=clock();
while(i)
{
  fw::math::mat44 m;
  --i;
}
c=clock()-c;

10回の平均をとった

inline mat44::mat44() : _11(1.0f),_12(0.0f),_13(0.0f),_14(0.0f),_21(0.0f),_22(1.0f),_23(0.0f),_24(0.0f),_31(0.0f),_32(0.0f),_33(1.0f),_34(0.0f),_41(0.0f),_42(0.0f),_43(0.0f),_44(1.0f)
----1.900s----

inline mat44::mat44(){
_11=_22=_33=_44=1.0f;
_12=_13=_14=_21=_23=_24=_31=_32=_34=0.0f;
}
----1.370s----

最適化の有無、デバッグの有無で優劣は変わらず
そんなはずないって言われると気になるな・・・
514デフォルトの名無しさん:2008/08/26(火) 15:16:12
コンパイラの吐いたアセンブリソース読んで勝手に納得しろ
515デフォルトの名無しさん:2008/08/26(火) 15:29:15
何でそんな言い方するの?
516デフォルトの名無しさん:2008/08/26(火) 15:33:42
ご・・・ごめん///
517デフォルトの名無しさん:2008/08/26(火) 15:39:06
代入順が違うから等価じゃない
518デフォルトの名無しさん:2008/08/26(火) 16:10:46
マジだ、代入順同じにしたら同じになった!
ここから先は514の言うようにアセンブラと闘わないと分かりそうにないな^^;
519デフォルトの名無しさん:2008/08/26(火) 16:49:43
依存するクラスとはどういう意味ですか?今勉強してる本に書いてあったのですが解説がなかったので
調べてみたけど分からなかったので教えていただけませんか。

//=============================================================
// Renderer.h
// レンダラークラスの定義
//=============================================================

#ifndef _Renderer_h_
#define _Renderer_h_

#include <d3d9.h>
#include <d3dx9.h>

#include "Common.h"

//=============================================================
// 依存するクラス
//=============================================================
class Scene;

//=============================================================
// Renderer
// レンダラークラス
//=============================================================
class Renderer
{
public:
520デフォルトの名無しさん:2008/08/26(火) 16:52:49
>>519
いそん 【依存】
(1)他のものにたよって成立・存在すること。
「食糧の大半を外国に―する」
521デフォルトの名無しさん:2008/08/26(火) 17:01:30
要するに
//=============================================================
// 依存するクラス
//=============================================================
class Scene;

を記述しないとコンパイルできないって事ですか

ありがとうございます!
522デフォルトの名無しさん:2008/08/27(水) 03:59:27
>>513
あー、初期化リストだとシーケンスポイントが挟まるから、最適化機がいろいろがんばらないと
同じ値の設定をまとめるような形にはならないのかもしれないね。
523デフォルトの名無しさん:2008/08/27(水) 14:21:55
マトリョーシカ(ロシア語だったような)っていうコンパイラ持っていませんか?
いい加減なコードもコンパイラを通るって有名なんですが?
524デフォルトの名無しさん:2008/08/27(水) 14:24:16
訂正

マトリョーシカ(ロシア語だったような)っていうコンパイラ持っていませんか?
いい加減なコードもコンパイラを通るって有名なんですが。
525デフォルトの名無しさん:2008/08/27(水) 14:44:02
いい加減なコードが通るコンパイラがいいのか?
526デフォルトの名無しさん:2008/08/27(水) 15:22:07
いい加減な動作をしそうな気がする
527デフォルトの名無しさん:2008/08/27(水) 15:23:15
いい加減な人間が実行するから問題なし
528デフォルトの名無しさん:2008/08/27(水) 15:44:36
>>523

そんなコンパイラ聞いたことないぞ

専門学生が卒業制作で作ったようなやつか?
529デフォルトの名無しさん:2008/08/27(水) 15:46:25
インライン展開についての質問です
あるクラスのオペレータのオーバーロードで

__inline const hoge &hote::operator + () const;
とするとインライン化されるのですが

__inline const hoge hote::operator + () const;
とするとインライン展開されずに関数呼び出しになります

内部処理は*thisを返しているだけです
インライン展開できない条件を調べてみたところ、以下の条件が当てはまるのかと思うんですが
「コピー構築されたオブジェクトを値で受け取る関数を、-GX/EHs/EHa でコンパイルした場合。」
良く理解できず、解決方法が分かりません。どうすれば値渡しでインライン展開できるでしょうか
530デフォルトの名無しさん:2008/08/27(水) 16:02:44
細かいことは気にするな。
それよりやるべきことはいっぱいある。
531デフォルトの名無しさん:2008/08/27(水) 16:14:02
細かいミスは気にしないでください
空のデストラクタを定義していたんですが、それをやめたらうまくいきました。
値渡しだとデストラクタが走るのは分かるんですが、インラインできない理由はよく分かりません^^;
532デフォルトの名無しさん:2008/08/27(水) 16:19:19
ということは、例外が投げられたときにデストラクタを呼ぶコードを吐かないといけないからだな。
529にあるコンパイラオプションはどれも例外処理を使用可能にするものばかりだ。
533デフォルトの名無しさん:2008/08/27(水) 16:39:14
なるほど、そういうことでしたか。スッキリしました^^
534デフォルトの名無しさん:2008/08/27(水) 20:25:40
マトリョーシカってプロトコルスタックに例えられることがあるよね。入れ子ってことで。
535デフォルトの名無しさん:2008/08/27(水) 21:46:35
いや、ないよ
536デフォルトの名無しさん:2008/08/27(水) 23:13:45
にじゃなくてがだろ
537デフォルトの名無しさん:2008/08/27(水) 23:58:52
文字列リテラルってstring型に暗黙変換されますよね?
しかし

bitset<5> bs("10101"); //エラー
bitset<5> bs(string("10101")); //OK

という結果になるのですが、なぜ前者のケースでstring型に暗黙変換
されないのでしょうか?
538デフォルトの名無しさん:2008/08/28(木) 00:03:58
引数がconstだから
539デフォルトの名無しさん:2008/08/28(木) 00:05:20
暗黙変換されないって
540デフォルトの名無しさん:2008/08/28(木) 00:07:13
>>537
explicitだから
541デフォルトの名無しさん:2008/08/28(木) 00:41:44
string str = "abc";

が可能なので、const char* からstringへの暗黙変換は定義されてると
思うのですが。
542デフォルトの名無しさん:2008/08/28(木) 01:01:46
ん、bitsetのbasic_stringを受け取るコンストラクタがテンプレートだからじゃないの?

template<size_t N>
class bitset {
public:
 // こっちが本物:エラーになる
 template <class CharT, class Traits, class Allocator>
 explicit bitset(const basic_string<CharT, Traits, Allocator>&) {}

 // 確認用:こっちはOK
 explicit bitset(const string&) {}
};

const char*からでは、basic_stringのテンプレートパラメータを推論できない

ちなみにC++0xではconst char*を受け取るコンストラクタが追加される
543デフォルトの名無しさん:2008/08/28(木) 01:05:43
>>542
ありがとうございます。

メンバテンプレートのコンストラクタだからですね。
544デフォルトの名無しさん:2008/08/28(木) 02:04:29
クラス定義の末尾で ; を落としただけなのに
「istreamが再定義されています」とかわけの分からないエラーが出るのは悔しいです。
(クラス定義の次の行にstd::istreamを戻り値に持つ関数が定義されている)
ちゃんと「クラス定義の末尾に ; を付け忘れてますよ。ふふふ。」と優しく教えてください。
545デフォルトの名無しさん:2008/08/28(木) 02:06:43
>>544
大丈夫、そのうち自身の脳みそがそう指摘してくれるようになるから。
546デフォルトの名無しさん:2008/08/29(金) 10:48:45
テンプレートについて質問があります。
以下の[Base.h]でDerivedを宣言した時にBase<T>の型は解決して
[Base.cpp]ではBase<int>::funcがコンパイルされると思うのですが、
リンクエラー(Base<int>::funcがない)になります。
これはどう理解すればよいでしょうか?

[Base.h] // ヘッダファイル
template <typename T> struct Base { T func(void); }; // テンプレートクラス
struct Derived : Base<int> {}; // 型の解決(?)したテンプレートクラスを継承したクラス

[Base.cpp] // 実装
#include "Base.h"
template<typename T> T Base<T>::func(void) { return 0; }

[main.cpp]
#include "Base.h"
int main(void) {
 Derived d;
 d.func(); // リンクエラー
return 0;
}
547デフォルトの名無しさん:2008/08/29(金) 11:03:39
テンプレート全般は、普通、宣言と実装を別けられない。
ヘッダにインラインで書くべき。
exportキーワードで別けられるコンパイラもあるが、gccもBCCもVCもダメ。
548デフォルトの名無しさん:2008/08/29(金) 11:05:33
>>546
http://www.google.com/search?q=C%2B%2B テンプレート ヘッダ 実装
549546:2008/08/29(金) 11:26:32
>>547-548
どうも。
テンプレートでは宣言と実装を分けないという基本的な考え方は理解しているのですが、
それは結局はコンパイル時に型解決ができないからですよね。
>>546のコードはどうして型解決ができていないのかというのが質問の趣旨です。
例えば[Base.cpp]内で
Base<int> dummy;
とダミー変数を用意してもダメでした。
550デフォルトの名無しさん:2008/08/29(金) 11:31:11
コンパイラの気持ちになって考えればよく分かる
551デフォルトの名無しさん:2008/08/29(金) 11:33:14
なんか基本が出来てないような気がするが・・・
実装というのは関数の実装だ。
template<typename T> T Base<T>::func(void) { return 0; }
↑これがダメなの。

型を全部指定したらそれはもはやテンプレートではない。
struct Derived : Base<int> {.....のメンバ関数はcppに実装を書いても通る。
552デフォルトの名無しさん:2008/08/29(金) 11:42:24
Base.cpp に template class Base<int>; って書くといいよ
553デフォルトの名無しさん:2008/08/29(金) 11:44:06
だよな…
それなら最初からint func(void)にしとけばいいじゃんってことになるからな
554546:2008/08/29(金) 11:48:58
# 結果を書いている途中で>>551以降のコメントが…。
# とりあえず載せます。

コンパイラの気持ちは結局わからなかったのですが、
結果は明らかになりました。

[Base.cpp]
#include "Base.h"
template<typename T> T Base<T>::func(void) { return 0; }
Base<int> dummy;
// ↑これだけだとアウト:オブジェクトファイルBase.oの中身は空っぽ
// ↓これを加えるとOK:Base.o
void func(void) { dummy0.func(); }

つまり、コンパイルされるのは用いられている関数のみでした。
クラスインスタンスを生成しても、使われなかった関数はコンパイルされない、というのは意外でした。
555546:2008/08/29(金) 11:50:54
>>552
どうも!それが一番の解決策でした!
556デフォルトの名無しさん:2008/08/29(金) 11:59:04
クラスhogeにメンバa,b,cがあり、hoge h1,h2,h3を作ったとして、h1=h2+h3とやった際に
h1.a=h2.a+h3.a
h1.b=h2.b+h3.b
h2.c=h2.c+h3.c
と同等のパフォーマンスを出したく、調べていたらRVOと言う方法を見つけたんですが
__inline hoge hoge::operator + ( const hoge &v ) const
{ return vec3(x+v.x,y+v.y,z+v.z); }

とした場合、アセンブラ命令で15命令になってしまいました
RVOではオブジェクトの作成&削除は避けれても値の複製事態は避けられないのでしょうか?
557デフォルトの名無しさん:2008/08/29(金) 11:59:12
質問です。
関数ポインタについてなのですが

void test(IHoge*(func)(const char*));
という関数に、
CHoge* hoge(const char*);
を渡すことができず、エラーになってしまいました。

IHogeはCHogetの基底クラスのため、暗黙のアップキャストが行われるのを期待したのですが・・・
hoge関数の返り値を変更せずに解決する方法はありませんでしょうか?
558デフォルトの名無しさん:2008/08/29(金) 12:18:07
funcの前に*
559デフォルトの名無しさん:2008/08/29(金) 12:28:22
>>557
IHoge* hogeWrapper(const char* s) { return hoge(s); }
を渡せばいいんじゃない
560デフォルトの名無しさん:2008/08/29(金) 13:03:33
>>558
うーん、足してみたけどダメでした

>>559
結構な数のラッパーを書くことになるので、避けたいところです
561デフォルトの名無しさん:2008/08/29(金) 13:23:53
>>557

キャスト使うとか?
↓こんな感じ。


// 関数ポインタの型をtypedefしておく。
typedef IHoge*(*RetIHogeFun)(const char*);

// test関数に渡すときにキャストする。
test((RetIHogeFun)hoge);
562デフォルトの名無しさん:2008/08/29(金) 13:41:03
>>561
できました!
なるほど、関数ポインタ型にキャストしてやる(書きやすいようにtypedefもしてやる)わけですね。
ありがとうございます。
563デフォルトの名無しさん:2008/08/29(金) 15:39:21
たとえばvectorのメンバを持ったクラスを設計するとき
ヘッダーでincludeせずcppの中でvectorをincludeする書き方
ってどんなものがあるでしょうか。
とりあえずメンバを*voidにしておくくらいしか思い浮かばない・・。
564デフォルトの名無しさん:2008/08/29(金) 15:45:40
「pimplイディオム」でググれ
565デフォルトの名無しさん:2008/08/29(金) 15:47:38
pimplイディオム
566デフォルトの名無しさん:2008/08/29(金) 15:55:52
あれタルいよな
567563:2008/08/29(金) 16:39:25
pimplイディオム・・・なんとなくわかったようなわからないような。
もうちょっと学んでみるけど、これ使ってもポインタにするしかない?
それtも書き方次第なのかな。
568デフォルトの名無しさん:2008/08/29(金) 18:19:16
vectorに限らず、実体をメンバに持つには、vectorのサイズがわからないと無理。
サイズを知るには実装部を見せるしかない。

なお、ポインタの他に、関数の引数や返り値とする場合も
サイズなしで宣言だけで可能。
でもメンバは無理。
(無茶するならExceptionalC++にchar[]で確保する方法が一応あったけど)

で、おまいが欲しているのはvectorの実体か?
void*を持たせて代わりにするなんてのは、vectorへのポインタ以外にあり得ないが。
569563:2008/08/29(金) 19:44:51
>>568
そう、cppでキャストして使う方法。
方法ということで*voidと書いたけど、もしpimplイディオムで実体持たせながら実現
できるならポインタがらみの問題も排除できるかな〜と。
簡単にはいかないようなので、ポインタがらみで問題を増やすなら素直にinclude
することにします。ありがとう。
pimplイディオムというものを知らなかったので勉強になりました。
570デフォルトの名無しさん:2008/08/29(金) 20:21:48
先生お願いします
Win32ではない標準のC/C++で他アプリを起動するには
Cのexec system popen のどれかを使用すると調べましたが
他にどのような手段があるのかご教授頂きたく

検索してもWindowsAPI関連サイトが多すぎて歯がゆいっす
571デフォルトの名無しさん:2008/08/29(金) 20:57:04
spawnとか?
どれも最終的にはCreateProcessが呼ばれる
気にしてどーすんの
572デフォルトの名無しさん:2008/08/30(土) 00:38:56
標準のC/C++にはsystem()しか無いだろ
573デフォルトの名無しさん:2008/08/30(土) 03:47:15
エラー処理や完了待ちを考えると標準でがんばるのはつらい
574デフォルトの名無しさん:2008/08/30(土) 04:00:20
いや、system() さえあれば何でもできるぞw
575デフォルトの名無しさん:2008/08/30(土) 23:08:19
よく、「global変数はなるべく使うな」といわれますが、
つまり、std::coutは窓から投げ捨てろという事ですか?
576デフォルトの名無しさん:2008/08/30(土) 23:10:58
gotoを躊躇無く使える結城がほしい
誤変換残しちゃえ
577デフォルトの名無しさん:2008/08/30(土) 23:27:36
>>575
cout を使う関数よりは ostream を引数に取る関数のほうが汎用性が高く再利用しやすいということ。
578デフォルトの名無しさん:2008/08/30(土) 23:53:27
>>575
実際のところ、その言葉の本質は「大きなスコープで、読み書きされる」ことにあります。
coutから値を取得して本処理に影響を与えるようなコードは問題が有ると言えます。

coutなどは変数なのは、抽象インターフェイスを持たせるためで、
状態を保持させるのが目的ではありません。

グローバルであっても、読むだけの変数(定数)/書くだけの変数(cout他)は、
一般的には許容されと思います。
579デフォルトの名無しさん:2008/08/31(日) 00:22:56
Simple is best. に従うと、グローバル変数を使うのも一概には悪いとは言えない。
グローバル変数使うなって言うのはプログラムが規模が大きいときに
そんなものが沢山あると収拾がつかなくなるからであって、1画面に
収まるようなショートプログラムなんかでは躊躇無く使って構わない。
580デフォルトの名無しさん:2008/08/31(日) 00:29:41
std も、ある意味「グローバル変数」なんだが
581デフォルトの名無しさん:2008/08/31(日) 00:31:52
>>580 んなこたーない。
582デフォルトの名無しさん:2008/08/31(日) 00:33:57
>>578
>ショートプログラムなんかでは躊躇無く使って構わない。
そういう場合は害もほぼ無いので基本的には同意ですが、慣れも大事ですよ。

短いプログラム程、グローバル変数なんて無くても困りませんし、
困ってしまう人は、大きなプログラムでもグローバル変数を使ってしまうでしょうからね。
583582:2008/08/31(日) 00:43:01
× >>578
>>579
584デフォルトの名無しさん:2008/08/31(日) 00:50:10
>>171
金額もアレだけど、
それ以上にカードのみ+ドルだしな。
俺は買う気無いけど、あの売り方は流石にどうかと思う。
585デフォルトの名無しさん:2008/08/31(日) 00:52:18
誤爆スマン
586デフォルトの名無しさん:2008/08/31(日) 01:09:11
理解度
581 <= 578 ≪ 577
587デフォルトの名無しさん:2008/08/31(日) 01:17:18
581 (←別の話→) 578,577
577の「ostreamを引数」 = 578の「抽象インターフェイス」

つまり
理解度
586 ≪ 577-581
588デフォルトの名無しさん:2008/08/31(日) 02:53:08
ということは 581 は自分が何の話に参加しているのかさえ理解していないとまで言いきるのか
なかなか辛辣だな
589デフォルトの名無しさん:2008/08/31(日) 08:09:02
int& a = hogea, b = hogeb, c = hogec;
と書いたらaもbもcも参照になりますか?
590デフォルトの名無しさん:2008/08/31(日) 08:17:48
俺はそういう「ちょっとした疑問」は、とりあえず試して確認するようにしている。
int& a = hogea, b = 1;
と書いてコンパイルが通るかとか。

もちろん、厳密には規格に従っているか確認しなければいけないがね。
591デフォルトの名無しさん:2008/08/31(日) 09:12:19
型名のみの宣言で無い場合、&の修飾対象はaのみになるので
aしか参照型のintにならない。
592デフォルトの名無しさん:2008/08/31(日) 09:17:50
>>580, >>586, >>588
わざわざ上げて馬鹿を披露しなくても良いよ
593デフォルトの名無しさん:2008/08/31(日) 09:51:49
>>589
複数の変数を同時に宣言することについて。

メリット
 ・型を書く必要が無くなり、ソースの文字数を減らせる。
デメリット
 ・*や&を含む場合、その型名をスマートポインタや
  テンプレート引数に変更すると壊れる。
 ・>>591の仕様を知らない人が、ソースを誤読する。
  (知らない構文と思うのでなく、勘違いしたまま読み進めてしまう)

全ての修飾が除かれるわけではなく、例えば、
  volatile int a=0;
  volatile int* b[]={&a}, c=a;
のとき c は volatile int になる。
594デフォルトの名無しさん:2008/08/31(日) 14:18:10
そういう面倒な仕様を考えると
基本的に複数行に分けて書いた方が良い
595デフォルトの名無しさん:2008/08/31(日) 15:27:37
C++0xでいろいろ拡張されるようですが、既存のライブラリの問題点を
改良する動きってあるのでしょうか。一貫してない命名規則とかvalarray
のような使い勝手の悪い設計とか。wiki見てもあんまりそのあたり書いて
ないですよねぇ。
596デフォルトの名無しさん:2008/08/31(日) 15:33:01
下位互換を取っ払うわけがない
597デフォルトの名無しさん:2008/08/31(日) 15:33:58
基本的には互換性重視じゃない?
今は組み込み系にも広く使われてるんだから、勝手に変えられたら困るなあ
598デフォルトの名無しさん:2008/08/31(日) 15:38:55
別に組み込みには従来のコンパイラ使えばいいだけだし。
互換性互換性言ってたらいつまでたっても汚いまんまではないの。
599デフォルトの名無しさん:2008/08/31(日) 15:41:11
>>598
Cの標準化以前の時代からの互換性を引っ張りつづけてるんだから、
いまさら方向転換なんてできないよ。

そういうの嫌いなら一ヶ月ごとにコンパイル通らなくなるD使えばいい。
600デフォルトの名無しさん:2008/08/31(日) 15:53:09
古い設計残しつつも、代替となる新しい優れた方法を同時に提供。
ゆくゆくは折りを見て古い設計がフェードアウト→廃止みたいな
感じで綺麗にしてくれないかな。HTMLみたいに。
601デフォルトの名無しさん:2008/08/31(日) 16:14:50
valarrayは残したままnumericarrayとか新設すればいいだけの話
602デフォルトの名無しさん:2008/08/31(日) 18:36:09
C++0xの拡張は、auto以外はほぼ下位互換です。

auto以外で私が知ってる下位互換じゃなくなる部分では
SFINAEの仕様が明確化されるので今まで曖昧だった部分を使っていたら
コンパイルエラーになるかもしれない、というとこです。

それ以外は基本的に"変更"というのはないです。今後もないでしょう。
603デフォルトの名無しさん:2008/08/31(日) 18:37:47
C#みたいにObsoleteな要素つかったらコンパイラが教えてくれるとうれしい
strstreamとか
604デフォルトの名無しさん:2008/08/31(日) 18:57:39
605デフォルトの名無しさん:2008/08/31(日) 19:14:37
重要なのは604が誰かということだ。
606デフォルトの名無しさん:2008/08/31(日) 19:26:02
604のリンク先の「〜は僕です」って何なのよ

名乗りたいなら最初からトリップつけときゃいいのに・・・
つかこういうつまらん名乗りごっこがしたいならハテナに引きこもっていてほしい
マジウザい
607デフォルトの名無しさん:2008/08/31(日) 19:36:33
C++0xのまとめ関連でお世話になってます
608デフォルトの名無しさん:2008/08/31(日) 19:49:51
>>601
auto_ptr非推奨でunique_ptr新設とかまさにそんな感じ。
609デフォルトの名無しさん:2008/08/31(日) 20:10:20
>>606
その後のコメントで晒されたwって言ってるから、
604は本人じゃなさそう。
610デフォルトの名無しさん:2008/08/31(日) 21:17:14
611デフォルトの名無しさん:2008/08/31(日) 21:49:15
>>602
キチに粘着されたようだなw
質問以外でageてるから>>586=>>586=>>604と予想
612デフォルトの名無しさん:2008/08/31(日) 21:51:08
なんにせよ自分から名乗っておいて「晒された」はねえよな
613デフォルトの名無しさん:2008/08/31(日) 22:00:16
名乗ったつってもTwitterだしな。アレもおよそ内輪コミュ系だよ。
貼られて困ること書いたら馬鹿だけど、一応晒されたとは言えると思う。
614デフォルトの名無しさん:2008/08/31(日) 22:04:01
結果として内輪コミュになってるだけ
晒されて困るならプライベートモードにでもすりゃいいのに
615613:2008/08/31(日) 22:07:30
誤解を招きそうなんで補足。
>>602が貼られて困ること書いたって意味では無くて、
誰でも見れる状態の内輪の会話みたいなものって意味ね。
616613:2008/08/31(日) 22:09:08
遅かったです(^q^)
617デフォルトの名無しさん:2008/08/31(日) 22:14:16
誰でも見ていいのならどうして2chに晒されたのを大騒ぎするのか
理解に苦しむね
618デフォルトの名無しさん:2008/08/31(日) 22:20:15
俺としては>>606, >>612, >>614, >>617
たかがtwitterのコメにやけに突っ掛ってるのも不思議だと思うけどな
619デフォルトの名無しさん:2008/08/31(日) 22:23:35
要は、604のリンク先の奴がそういう意識が低かっただけの話
そして、そういう奴がブログ炎上を引き起こす
今回はブログじゃなかったからダメージ少なくてよかったな
いい教訓になったじゃん
620デフォルトの名無しさん:2008/08/31(日) 22:28:30
見たところ痛いこと書いてるわけじゃないようだし
ブログ炎上とは違うと思うけどな
批判レスならともかく、ただの粘着がくれば普通は嫌がるだろ
621デフォルトの名無しさん:2008/08/31(日) 22:28:58
おまえらもっと有益な話をお願いします
622デフォルトの名無しさん:2008/08/31(日) 22:32:38
623デフォルトの名無しさん:2008/08/31(日) 22:35:28
スレ違いはそろそろ終わりにと書こうとしたら書かれてたw

>>603
同意。
なんかあったような気がしてググッたけど見つからなかった。

#errorの警告版みたいなの無かったっけ?
624デフォルトの名無しさん:2008/08/31(日) 22:40:54
>>623
処理系依存じゃね?gccなら何か言ってくれそうだけど
625デフォルトの名無しさん:2008/08/31(日) 22:50:50
#warning this is warning message.
int main (void) { return 0; }

GCCならこれでwarningが出る
VCなら#pragma message()かね・・・
626デフォルトの名無しさん:2008/08/31(日) 22:52:06
確かに処理系依存しかなさげ。
VC++なら#pragma messageでコンパイル時にメッセージ出せる。
メッセージなんで警告数は0になるけど。
627デフォルトの名無しさん:2008/08/31(日) 22:59:50
VCの方も見つけた。
ディレクティブでなく、処理系拡張の修飾だった。

  __declspec(deprecated("test")) void f(){}

としておいて、これでf()を使うと、
   warning C4996: 'f' が古い形式として宣言されました。
   'f' の宣言を確認してください。
   メッセージ: 'test'
って警告が出る。
f()を使わなかったら警告は出ない。
628デフォルトの名無しさん:2008/08/31(日) 23:12:39
crtdefs.hに
  #if _MSC_FULL_VER >= 140050320
  #define _CRT_DEPRECATE_TEXT(_Text) __declspec(deprecated(_Text))
  #else
  #define _CRT_DEPRECATE_TEXT(_Text) __declspec(deprecated)
  #endif
って書いてあった。

この条件に、_MSC_VERでVC++限定にする#ifも含めて、
別途マクロを定義しておけば良さそう。
直接書いちゃうとVC++でしかコンパイル出来なくなるし。
629デフォルトの名無しさん:2008/08/31(日) 23:22:48
>>603
というわけで、とりあえずVC++でのObsoluteみたいなもの。
gccの#warningも混ぜられそうだけど今手元にgcc無いので。

#if _MSC_VER >= 1300
  #if _MSC_FULL_VER >= 140050320
    #define OBSOLUTE(_Text) __declspec(deprecated(_Text))
  #else
    #define OBSOLUTE(_Text) __declspec(deprecated)
  #endif
#else
  #define OBSOLUTE(_Text)
#endif

OBSOLUTE("use f2()") void f(){ /*...*/ }

void f3(){
  f(); //警告
}
630デフォルトの名無しさん:2008/08/31(日) 23:25:34
GCCにも__attribute__((deprecated))みたいのがあったと思う
使えるバージョンは知らん
631デフォルトの名無しさん:2008/08/31(日) 23:31:43
c++でなにか簡単なゲームを作れという課題があるのですが、どうにもネタが生まれません
というか、クラスまでしかやっていないので、大したものは作れないのですが。
助けt
632デフォルトの名無しさん:2008/08/31(日) 23:33:50
乱数あてゲーム!
あなたはエスパーか
633デフォルトの名無しさん:2008/08/31(日) 23:35:29
3並べでも作れよ
初歩的だが考えるルーチンはこれからのためになる
634デフォルトの名無しさん:2008/08/31(日) 23:36:38
>>629
それを言うならOBSOLETEだ
635デフォルトの名無しさん:2008/08/31(日) 23:36:39
>>630
d
確認してないけど、これで良いかも。
>>629の2個目の#elseの前に追記で。

#elif (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))
  #define OBSOLUTE(_Text) __attribute__((deprecated))
636デフォルトの名無しさん:2008/08/31(日) 23:37:59
>>633
俺も最初は3並べ作ったなあ。
盤と目をクラスとして設計するのもいい練習になるし。
637デフォルトの名無しさん:2008/08/31(日) 23:39:26
>>634
ごめんw素で間違えてた。
638デフォルトの名無しさん:2008/09/01(月) 01:42:42
class A
{
class B
{
void F();
};
};

と.hに宣言した場合、
.cppに実装を書く場合、
void A::B::F(){ ... }
と書くと、A::Bは宣言されてないと怒られます。なんで?
gcc バージョン 4.2.3 使用中。

インナークラスは宣言時に実装も書かないとダメ?
639デフォルトの名無しさん:2008/09/01(月) 02:04:31
void A::B::F()の宣言が書かれている(ヘッダ)ファイルを void A::B::F()を定義する前にインクルードしていないとか
640デフォルトの名無しさん:2008/09/01(月) 12:38:35
>>631
ほれ。
クイズゲーム作ってやったぞ

$ cat a.cc
#include <cstdio>
using namespace std;
int main()
{
int hoge;
printf("日本の首都は?");
printf("1.東京 2.京都 3.奈良");
scanf("%d", &hoge);
printf(hoge == 1 ? "正解" : "不正解");
return 0;
}
641デフォルトの名無しさん:2008/09/01(月) 12:42:40
ああ、相当\nが抜けてたわwww
642デフォルトの名無しさん:2008/09/01(月) 12:48:20
5点
643デフォルトの名無しさん:2008/09/01(月) 13:09:00
5点満点だよな
644デフォルトの名無しさん:2008/09/01(月) 13:14:25
オブジェクト指向で作りなさい
645デフォルトの名無しさん:2008/09/01(月) 13:18:59
>>640
>#include <cstdio>
>using namespace std;
ワロタ
646デフォルトの名無しさん:2008/09/01(月) 14:26:23
テンプレートクラスの前方宣言て、

template<class T> class hoge;

こんな感じでおk?
647デフォルトの名無しさん:2008/09/01(月) 14:33:19
そういえば、.hがつくC言語の古いタイプのヘッダと違って、頭にcを
付けて.hを付けない新しいタイプのC言語のヘッダって、std名前空間に
C言語のモジュールを入れるためのヘッダじゃなかったっけ?
でも実際はstd名前空間に入ってなくて、グローバル名前空間だよねぇ。
なんでだろ。
648デフォルトの名無しさん:2008/09/01(月) 14:40:10
>>647
それはVC6くらいだ。今時のはちゃんとstd名前空間に入れてある。
が、どいつもこいつも中で<*.h>をインクルードしているので、
グローバル名前空間でも使えてしまうのは相変わらずだが。
649デフォルトの名無しさん:2008/09/01(月) 14:50:44
じゃあ、std::を付けても付けなくてもC言語のモジュールが使えちゃうわけか。
なんだかなぁ。実装者の都合かな。
650デフォルトの名無しさん:2008/09/01(月) 15:27:43
手抜き
651デフォルトの名無しさん:2008/09/01(月) 15:31:44
しかしプログラマーとしてはどうすればいいんだ?
std::付けなくてもコールできるけど、移植性を考えたらstdにあるつもりで
プログラムしなきゃいけないんだよな。でもそんなことやる奴いるのか?
652デフォルトの名無しさん:2008/09/01(月) 15:32:52
はあ??
653デフォルトの名無しさん:2008/09/01(月) 15:41:36
規格書通りにしないと移植性が保証されないだろ
654デフォルトの名無しさん:2008/09/01(月) 15:52:09
>>653
それはその通りだが真っ当なプログラマなら当然そのように書くだろ。
>>651で何を言いたいのか分からない。
655デフォルトの名無しさん:2008/09/01(月) 15:53:11
<cnanntoka>でグローバル空間にstd空間と同じものができるという保証はない。
よってstd名前空間を頭につける、という一択しかない。
656デフォルトの名無しさん:2008/09/01(月) 16:05:27
そこで恐怖のsize_tとptrdiff_t
657デフォルトの名無しさん:2008/09/01(月) 16:19:38
>>654
何が真っ当なプログラマだよ規格書も守らずに
658デフォルトの名無しさん:2008/09/01(月) 16:23:01
もうやだこのスレ。
日本語通じない馬鹿がなんでこんなにいっぱいいるの?
659デフォルトの名無しさん:2008/09/01(月) 16:28:15
>>658
逆だろ。
日本語が通じない馬鹿ではなくて、正しい日本語で相手に自分の
意志をうまく伝えられない自分の馬鹿さ加減を何とかしろ
660デフォルトの名無しさん:2008/09/01(月) 16:28:35
まあ流しとけw
661デフォルトの名無しさん:2008/09/01(月) 17:08:21
>>658
たぶん一人、二人くらいだと
662デフォルトの名無しさん:2008/09/01(月) 17:14:28
>>656
そこで泣く泣く#define SIZE_Tですよ
663デフォルトの名無しさん:2008/09/01(月) 18:07:53
エスパーでない俺がエスパーしてみるてst

話題提起者(>>651=>>653=>>657)

>>651「ちゃんとstd空間として扱ってる奴居るの?」
>>652「std空間として扱うだろ常識的に考えて」
>>653(652が文意を理解してないと考えて言い換える)
   「std空間としてじゃないとまずいんだろ?」
>>654「当然std空間として扱うだろ常識的に考えて」
>>655「std空間一択」
>>656「std::size_tが無い恐怖のEmbedded・・・」
>>657(654が"だが"という言葉を使ったため、
   "そのように"をグローバルの方だと認識)
   「グローバルは真っ当じゃないだろ」
>>658「勘違いしてるオワタ」

※ 結局全員 std空間として扱うのを推奨
664デフォルトの名無しさん:2008/09/01(月) 22:23:46
エスパーならまかしておけ。
>>651が言いたいのは、たいていのコンパイラは新しいC言語ヘッダ(c○○)
を使う場合、std::付けなくてもC言語の標準関数がコールできる。
ただし、std::付けないで組まれたプログラムは、律儀にstd::を付けないと
コールできないようにしているコンパイラ環境では、コンパイルできなく
なってしまう。そういう意味で、移植性を考えるなら、std::がいらない
状況でもstd::を付けてプログラミングするべきという話なんだろう。
665デフォルトの名無しさん:2008/09/01(月) 23:15:34
エスパーじゃないけど俺も664の言うようにしか解釈できなかったよ。
666デフォルトの名無しさん:2008/09/02(火) 00:50:34
代入演算子関数は非静的クラスメンバじゃなきゃダメよ(13.5.3)って言われてて
代入演算子とは=とか+=とかみたいなの全部(5.17)って書いてるのに
VCとGCCの両方ともグローバルなoperator+=()作れちゃうんだけど
これってどうなの
グローバルな+=とか*=とか作っていーの?
667デフォルトの名無しさん:2008/09/02(火) 01:33:47
ttp://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#221
によると、その制約は = のみってことで良さそげ。
668デフォルトの名無しさん:2008/09/02(火) 02:26:56
規格の書き方の方が曖昧だったのね
じゃ+=系は+や-と同じただの二項演算子として扱っちゃっていいのね

ありがとう
669デフォルトの名無しさん:2008/09/02(火) 05:32:49
教えてください。
C++の入出力処理は、ストリームバッファなるものを介して行われるようですが
出力時のバッファの役割はなんとなくわかるのですが、入力時のバッファの
役割ってどんな感じなのでしょうか。キーボードから入力してもバッファに
ため込むだけで、実際にプログラムに入力されないみたいなことがあるのでしょうか?
もっといえば、標準入力関数のreadとreadsomeの使い分けがわからないのです。
670デフォルトの名無しさん:2008/09/02(火) 05:49:34
>>669
read()は実際にストリームバッファに文字が入力されるまで
そこで停止して待つが、readsome()はストリームバッファに文字
があろうとなかろうと読み取ろうとして停止しない。

もちろんどちらもfailbitやeofbitが設定される。
671669:2008/09/02(火) 07:31:36
>>670
ありがとうございます。
動作の違いは理解できました。

が、readsome()の使いどころって想像つきませんね。
まぁキーボードから入力するなどという単純なプログラム作ってるうちは
無理なんでしょうが。
672デフォルトの名無しさん:2008/09/02(火) 07:38:33
>>671
readsome()はファイル入出力で生きてくる。
というかstd::cinに対してistream::readsome()が正しく実装されている
処理系は少ないと思う。
673デフォルトの名無しさん:2008/09/02(火) 08:24:54
ヒント:リダイレクト
674デフォルトの名無しさん:2008/09/02(火) 08:26:40
メッセージループみたいな働きをさせられるんじゃね?
675デフォルトの名無しさん:2008/09/02(火) 09:29:30
min, maxがマクロで定義されていた場合,
std::min とか std::max とか std::numeric_limits<T>::min()
が置換されてしまうので,
呼び出すときに
std::min BOOST_PREVENT_MACRO_SUBSTITUTION (x, y)
などとしているのですが,長ったらしいので,
(std::min)(x, y)
と関数を括弧で囲みたいのですが,この書き方は規格的に合法でしょうか?
それか他にもっと上手な回避方法はないでしょうか?
676デフォルトの名無しさん:2008/09/02(火) 09:35:27
>>675
合法です。
677デフォルトの名無しさん:2008/09/02(火) 12:07:56
#undefでよくないか?
あと、もし<windows.h>のだったらNOMINMAXで抑制できる。
678デフォルトの名無しさん:2008/09/02(火) 13:01:58
>>651
http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#456
<c...> を使ったら std の名前が使えることは保証されるけどグローバルな名前は使えないかもしれない。
<....h> を使ったらグローバルな名前が使えることは保証されるけど std の名前は使えないかもしれない。

C++0x 以降に備えてこの方針に沿っておくことがおすすめ。
C++ 2003 のうちは、よくわからないってことで、しょうがない。
679デフォルトの名無しさん:2008/09/02(火) 14:08:22
実装が内部に持つコンテナのイテレータを返すメンバ関数をインタフェースに持ちたい場合,
どうすればよいでしょうか?

// インタフェース
struct Hoge {
 virtual HogeIterator begin(void);
};

// 実装
struct HogeImpl : Hoge {
 HogeIterator begin(void) { container_.begin(); }
 vector<int> container_;
};

インタフェースで typedef vector<int>::iterator HogeIterator; とすると実装が見えてしまうし,
インタフェース側で struct HogeIterator; と宣言だけしておいて実装部分で
struct HogeIterator : public vector<int>::iterator {
・・・
};
とするのは大変そうな気がするのですが。
680デフォルトの名無しさん:2008/09/02(火) 14:21:59
俺は実装が見えても気にしない派
681デフォルトの名無しさん:2008/09/02(火) 14:31:50
>>679
ややこしい文章だなw
イテレータがテンプレートクラスだった場合、
どう足掻いても仮想化出来ないんだからラップすればいい。

※ コンパイルもしてない

struct VirtualIterator {
 typedef VirtualIterator Myt;
 virtual ~VirtualIterator(){}
 VirtualIterator(const Myt& o){copy_from(o);}
 Myt& operator++() {incr(); return (*this);}
 virtual void incr() = 0;
 virtual void copy_from(const Myt& o) = 0;
};

struct Hoge {
 virtual VirtualIterator begin() = 0;
};

-- .cpp -----
struct IterImpl : VirtualIterator {
 std::vector<int>::iterator it;
 void incr(){ ++it; }
 void copy_from(const VirtualIterator& o){
  IterImpl* p = &o;
  it = p->it;
 }
};
682681:2008/09/02(火) 14:38:20
まあ言っても俺も >>680 に同意。
virtual自体滅多に使わないし、
pImplなんて余程のこと。
テンプレートクラスでおk。
683681:2008/09/02(火) 14:41:41
なんか実装隠す話とvirtualが混ざったけどまぁいいか。
684デフォルトの名無しさん:2008/09/02(火) 15:03:22
特定のクラス→自作クラスのキャストをオーバーロードはやり方が分かるのですが
自作のクラス→特定のクラスのキャストを自作クラス内部に記述するやり方ってないでしょうか?
データの配置が同様なのでコピーを作成したくないんです・・・
685679:2008/09/02(火) 15:49:38
>>681 ややこしい文章だなw
同意。

>>680 >>682
これも実は同意で、これまでそういう実装をしていました。
急に気になり始めてしまって…。(麻疹みたいなものですか)

↓みたいにできればシンプルでハッピーなのですが、現状不可です。

class HogeIterator; // in "Hoge.h"
typedef vector<int>::iterator HogeIterator; // in "Hoge.cpp"
686デフォルトの名無しさん:2008/09/02(火) 17:54:13
>>684
>コピーを作成したくない
Tokutei* a = new Jisaku(); ってこと?
これなら class Jisaku : public Tokutei{...}
と継承すれば良い。

それとも
Jisaku a;
Tokutei b = a;
ってこと?こっちは当然コピーってことになるけど。

>>685
>急に気になり始めてしまって
そんなふうに考えていた時期が(ry

>現状不可です。
>>681で書いた通り、直接では仮想化出来ないよ。
原理的に。
687デフォルトの名無しさん:2008/09/02(火) 20:37:49
>>684
>>686の言うように継承を使うか、
operator Tokutei &() { return reinterpret_cast<Tokutei &>(*this); }
を実装する。

データの配置が同じと言うからreinterpret_castにしてるが、
本当にメモリレイアウトが同じなのか?
そうだとしても偶然や実装依存ではないのか?
ってことはよく考えるべし。
688デフォルトの名無しさん:2008/09/02(火) 21:02:21
ファイルって入力用にオープンしたら、ストリームバッファにすべて
取り込まれていると考えていいの?
689デフォルトの名無しさん:2008/09/02(火) 21:12:05
>>688
そりゃあ必要に応じて取り込むでしょ
すべてではなく
690デフォルトの名無しさん:2008/09/02(火) 21:15:36
>>688
すべて取り込んでたら、
2GBの動画とかメモリ不足で再生出来なくなるだろ
691デフォルトの名無しさん:2008/09/02(火) 22:57:10
ということは、どれほどのデータ量を一度にストリームバッファに取り込む
かは、実装依存てこと?
692デフォルトの名無しさん:2008/09/02(火) 23:20:01
そりゃそうでしょ
693デフォルトの名無しさん:2008/09/03(水) 05:09:28
言語以前の問題だろ…
>>688はゆとりか?
694デフォルトの名無しさん:2008/09/03(水) 06:26:21
想像力ゼロの人間が何一つ試さないと、こうなる。
695デフォルトの名無しさん:2008/09/03(水) 06:30:58
なんでこんなに叩かれるのか分かりませんがとりあえずありがとぐございました
696デフォルトの名無しさん:2008/09/03(水) 09:07:33
他人を↓ることで相対的に自分を↑ようとする人が多いからね。気にしないこと。
697デフォルトの名無しさん:2008/09/03(水) 13:21:31
http://pc11.2ch.net/test/read.cgi/tech/1217008269/523
http://pc11.2ch.net/test/read.cgi/tech/1218023777/662
ところでこいつはマトリョーシカなんて開発環境をどこで手に入れたんだろう?
698デフォルトの名無しさん:2008/09/03(水) 13:29:21
なぜグローバルリンクw
699デフォルトの名無しさん:2008/09/03(水) 14:24:33
2chは基本的にボケた的を射ていない質問をするとそれだけで
叩かれる傾向があるのさ。

だからちょっと敷居が高く感じるかもね。
700デフォルトの名無しさん:2008/09/03(水) 14:53:51
初学者の、なんてことない質問にいちいちつっかかる >>693-694
他所のスレで叩かれて八つ当たりしてるか、或いは生理不順なんだろう。
701デフォルトの名無しさん:2008/09/03(水) 15:05:15
C++の質問ですらないから少なくともスレ違いだなw
702デフォルトの名無しさん:2008/09/03(水) 15:06:23
ストリームバッファはC++じゃないの?
703デフォルトの名無しさん:2008/09/03(水) 15:38:53
この疑問の答に必要なのは、PCの基礎知識と、ほんの少しの当たり前の思考だけ。
あるいは、「初学者」には絶対無くてはならない「自分で試す精神」で、ほんの数行のコードを書いて実験するだけ。
つまり、まともなら質問自体が発生しない話。

PCの基礎知識すら無いか、当たり前の思考力すら無いか、初学者に必須の精神すら無いか。
いずれにせよ、「初学者の、なんてことない質問」になっていないから突っ込まれるんだよね。
704デフォルトの名無しさん:2008/09/03(水) 15:49:41
つまり燃料が欲しいだけだろ
705デフォルトの名無しさん:2008/09/03(水) 15:57:57
スルーするのが大人の対応
一々突っ込むのは(笑)
706デフォルトの名無しさん:2008/09/03(水) 16:01:05
ほんとに実装依存なんだろうか >>ストリームバッファ
707デフォルトの名無しさん:2008/09/03(水) 16:03:18
すいません。初心者です。
ファイルを入力用にオープンしたら、ストリームバッファにすべて取り込まれてるかを
調べる 「ほんの数行のコード」 を教えてください。

streambuf::in_avail() を使えば いいと思い以下のコードを確認しました。

#include <iostream>
#include <ostream>
#include <fstream>

int
main()
{
std::ifstream ifs("tmp.bin");
std::cout << ifs.rdbuf()->in_avail() << std::endl;
return 0;
}

環境 cygwin + g++(3.4.4) で 100Mbyte のファイルで 確認したら ファイルサイズがそのまま返ってきました。
$ g++ -Wall -O2 -g tmp.cpp
$ dd if=/dev/zero of=tmp.bin bs=1M count=100
$ ./a.exe
104857600
$

200Mbyte のファイルで確認しても同じでした。
よろしくお願いします。

708デフォルトの名無しさん:2008/09/03(水) 16:12:36
何を教えてほしいのかよく分からん
コードは自分で書いてるじゃん
709デフォルトの名無しさん:2008/09/03(水) 16:40:03
>>707
参考にならんかもしれんけどBCC5.9.3では0を返した
710デフォルトの名無しさん:2008/09/03(水) 17:38:23
ロシアから輸入したに決まってるだろJK
711デフォルトの名無しさん:2008/09/03(水) 17:44:04
最近、マトリョーシカの話題をあちこちでみかけるなw
712デフォルトの名無しさん:2008/09/03(水) 18:38:38
> アメリカのMicrosoftは、Microsoft C/C++を最初に世に送り出したとき、一般の顧客はまともなC++プログラムを書けないことを発見した。
> これではC++コンパイラを売っても儲けにならない。
> Microsoftのプログラマたちはこの問題に立ち向かうべく、20年の歳月と120億ドルの開発費をかけて研究を重ねた。
> その結果ついに、タイプミスをしても関数の名前を忘れても、どんな状況下でも適切な補完候補を提示できるIDEを開発した!!
>
>一方ロシアはマトリョーシカ(>>523)を使った。


みたいな?
713デフォルトの名無しさん:2008/09/03(水) 19:41:24
マトリョーシカってよくプロトコルスタックに例えられるよねって書いて、
逆だと突っ込まれたやつが来ましたよ。
714デフォルトの名無しさん:2008/09/03(水) 20:49:24
>>712
むしろそこはIDEじゃなくてC#が当てはまる気がする。
715デフォルトの名無しさん:2008/09/03(水) 23:37:56
でもSunに先を越されちゃいました^^;みたいな?
716デフォルトの名無しさん:2008/09/04(木) 01:27:01
入出力がらみなんですが、sentryオブジェクトはそのコンストラクタや
デストラクタで、ストリームの前処理と後処理を例外安全に行うRAII
オブジェクトということのようですが、実際何をやるんでしょうか。
自前で入出力演算子などをオーバーロードするときに、どういう場合に
使えばいいのでしょうか。
717デフォルトの名無しさん:2008/09/04(木) 01:44:24
>>716
C++標準ライブラリより。

sentryオブジェクトは入出力の途中で例外が生じても確実に
処理を終わらせるために設けられている。

出力演算子にsentryを使うには

std::ostream::sentry se(stream);
if (se) {出力を実行}

入力演算子に使うには

std::istream::sentry se(stream, true);
if (se) {入力を実行}
718デフォルトの名無しさん:2008/09/04(木) 01:45:46
但し、basic_istreamやbasic_ostreamにsentryを使うと
不必要にコストが高くなるので、basic_streambufを使うべき、
と書かれている。
719デフォルトの名無しさん:2008/09/04(木) 02:24:29
レスありがとうございます。

どうも、何をやるのかってのは、ブラックボックスなんでしょうかね。
720デフォルトの名無しさん:2008/09/04(木) 02:29:49
リバースエンジニアリングして解析すれば何とかわかるんじゃね
721デフォルトの名無しさん:2008/09/04(木) 04:41:07
char_traits<char>::eof()は、その文字型のeofを返しますが、
char_traits<char>::not_eof(c)は何をやる関数なのでしょうか。
722デフォルトの名無しさん:2008/09/04(木) 05:16:37
>>721
iがEOF以外の値であればiを返す
iがEOFであれば処理系依存であるがEOF以外を返す

つまり絶対にEOFを返さないメンバ関数
723デフォルトの名無しさん:2008/09/04(木) 08:09:33
コンストラクタのなかで
(*this) = rhs;
と自分自身のoperator=を呼び出すのは問題ないでしょうか?
724デフォルトの名無しさん:2008/09/04(木) 08:53:27
問題ないよ。やめたほうがいいけど。
725デフォルトの名無しさん:2008/09/04(木) 09:06:22
初期化子リスト書くの面倒だからな。やめた方がいいけど
726デフォルトの名無しさん:2008/09/04(木) 09:15:52
operator=をcopy&swapで実装して、copy constructorは全部書くほうが好きだな。
727デフォルトの名無しさん:2008/09/04(木) 15:04:56
>>722
ありがとうございました。
728デフォルトの名無しさん:2008/09/04(木) 16:25:26
すいません初心者です。
動的にTCHARの2次元配列を確保したいのですが、下のようなエラーがでます。
error C2440: '=' : 'TCHAR (*)[260]' から 'TCHAR' に変換できません。
こういった場合はどうすれば、いいんでしょうか?
メンバーにszParam[_MAX_PATH]を持った構造体を作ったりするんでしょうか?

TCHAR g_szParam;

void Test(void){
  int nCnt = 10;
  g_szParam = new TCHAR[nCnt][_MAX_PATH] //ここがエラー
}
729デフォルトの名無しさん:2008/09/04(木) 16:32:33
TCHAR (*g_szParam)[nCnt];
730デフォルトの名無しさん:2008/09/04(木) 16:37:19
あれTCHAR (*g_szParam)[_MAX_PATHt];
だっけ?
うろ覚えで答えたりしてすいません
731728:2008/09/04(木) 16:51:26
>>729 >>730 さん
有難うございました。1時間位悩んでたので助かりました。

TCHAR (*g_szParam)[_MAX_PATH];

void Test(void){
  int nCnt = 10;
  g_szParam = new TCHAR[nCnt][_MAX_PATH];
}
732デフォルトの名無しさん:2008/09/04(木) 18:21:24
>>731
このタイプのnewをした場合でも、解放するときってdelete[]でいいんでしたっけ?
delete[][]なんてことはないですよねw
733デフォルトの名無しさん:2008/09/04(木) 18:35:59
>>732
当たり前だろ。
勉強に3次元配列の確保と解放の仕方を書いてみなさい。
734デフォルトの名無しさん:2008/09/04(木) 18:40:04
int (*p)[2][3];

p = new int[4][2][3];

delete [] p;

こんなんでいいのかな?
735デフォルトの名無しさん:2008/09/04(木) 18:41:05
             ,.,.,.,.,.,.,.,.,__
           ,,;f::::::::::::::::::::::ヽ
           i::::::::/'" ̄ ̄ヾi
           |:::::::| ,,,,,_  ,,,,,,|
           |r-==( 。);( 。)
           ( ヽ  :::__)..:: }
        ,____/ヽ  ー== ;  ほほう それでそれで?
     r'"ヽ   t、   \___ !
    / 、、i    ヽ__,,/
    / ヽノ  j ,   j |ヽ
    |⌒`'、__ / /   /r  |
    {     ̄''ー-、,,_,ヘ^ |
    ゝ-,,,_____)--、j
    /  \__       /
    |      "'ー‐‐---''
736デフォルトの名無しさん:2008/09/04(木) 18:42:13
>>735
 ':,      ',   _____,,.. -‐ ''"´ ̄ ̄`"'' ー 、.,          /
  ':,    ',   >' ´             `ヽ.       /  し バ
   ':,     /                    ヽ.     ,'   な カ
    ':,   ,:' /   /   ,'´        ヽ.     ':,/Ti  i.   い に
. \    ,' /   /  ,'  !      ;   ',  ヽ__ /::::| | |   で 
   \  / ,'   ,'!  /!  !   ;  /!   i  「:::|'´::::::::| | .!.   く
     ∠__,!   / !メ、」_,,./|   /! / !   ハ! |__」<:::::」」 |.   れ
`"''  、..,,_  !  / ,ァ7´, `iヽ| / |ヽ、」ニイ、 |  ! |^ヽ、」」  |.   る
       i,/レイ i┘ i. レ'   'ア´!_」 ハヽ|   |   | ∠   ! ?
─--     /   !  ゝ- '       !    ! !   |   |  `ヽ.
      /   7/l/l/   、     `'ー‐ '_ノ!   |  i  |    ` ' ー---
,. -──-'、  ,人    `i`ァー-- 、  /l/l/l |    !. |  |
       ヽ.ソ  `: 、.   レ'    ',   u ,/|    |  !  |
 そ  知  i  /ーナ= 、 '、    ノ  ,.イ,カ    !  |  |
 の   っ  .|ヘ./|/レへ`>-r  =ニi´、.,_ |  i  ハ  ! ,'
 く   て   !     _,.イ´ヽ.7   /  /:::| /レ'  レ'レ'
 ら  る   |   /7:::::!  ○O'´  /::::::レ'ヽ.
 い  .わ  .|  /  /:::::::レ'/ムヽ.  /::::::::/   ヽ.
 ! !  よ   ! ./  ,':::::::::::!/ ハ:::::`´:::::::::::;'    ',
737デフォルトの名無しさん:2008/09/04(木) 18:43:43
けっきょく多次元配列なんて存在しないという結論でいいのかなw
どうやっても1次元。
738デフォルトの名無しさん:2008/09/04(木) 18:47:37
多次元配列は「〜配列へのポインタ」という形でしか存在しないんだな
739デフォルトの名無しさん:2008/09/04(木) 20:14:14
typedef int (*PA)[5];
PA *p = new PA[3];

この動的確保をtypedef無しに生で書くと
int (**p)[5] = new int (*[3])[5];
になると思ったのだが、コンパイル通らん。
どこが間違ってる?
740デフォルトの名無しさん:2008/09/04(木) 20:30:59
int (*pp)[5] = new int (*)[3][5];
741デフォルトの名無しさん:2008/09/04(木) 20:38:25
int (**p)[5] = new (int (*[3])[5]);
742デフォルトの名無しさん:2008/09/04(木) 20:45:45
>>741
ありがとうございます。

でもこれってどういうことなんですかね。new演算子の優先順位が
問題なんでしょうが、new int (*[3])[5]; だとコンパイラは
どう解釈しにいってるんだろう。
743デフォルトの名無しさん:2008/09/04(木) 20:46:14
740は間違いな。741で。
どうもカッコがないとうまくパースできないらしい。
この問題は関数ポインタの配列を確保しようとする時にも
同様に発生した。

詳しい方解説ヨロ
744デフォルトの名無しさん:2008/09/04(木) 21:03:24
new int (*[3])をintのコンストラクタだと思って、
結果のint*に配列添え字演算子[5]を付けてると解釈する
でもコンストラクタ引数の*[3]が理解できないからエラー

だと思う多分
745デフォルトの名無しさん:2008/09/04(木) 21:14:40
なるほどそういう事かサンクス

どてもこのカッコが異質で慣れないもんだから時々悩んでしまうんだよな
746デフォルトの名無しさん:2008/09/04(木) 22:35:57
結局typedefすればいいという結論
747デフォルトの名無しさん:2008/09/04(木) 22:52:40
この場合のtypedefはした方がいいね
いらない事で悩んで時間を無駄にするよりまし
748デフォルトの名無しさん:2008/09/04(木) 23:27:21
この場合、というよりセマンティクスを優先することだな。
ただのバッファで無い限り、1要素に対して、
何か意味のある名前を与えることが出来るはずだ。
749デフォルトの名無しさん:2008/09/05(金) 00:13:17
>>724
いや、レアケースではあるけど問題あるからw
750デフォルトの名無しさん:2008/09/05(金) 00:32:42
>>749
どういうケース?
751デフォルトの名無しさん:2008/09/05(金) 00:43:51
代入子演算関数が自分自身のクラスの仮想関数を
呼び出している時とか?
752デフォルトの名無しさん:2008/09/05(金) 01:21:37
あ、ごめん、逆の( operator=() から placement new を利用する )パターンと間違えた。忘れてくれ。
753デフォルトの名無しさん:2008/09/05(金) 22:32:43
> いらない事で悩んで時間を無駄にするよりまし

そういうノロマまは開発のテンポについていけないから、窓から飛び降りたほうがいい
754デフォルトの名無しさん:2008/09/06(土) 07:58:07
std::vectorみたいに
・ランダムアクセス可能
・コピーすると中身もコピーされる
・個数を記憶している

けど、push_backとかで追加することはできないコンテナってある?
755デフォルトの名無しさん:2008/09/06(土) 08:17:13
>>754
boost::array
756デフォルトの名無しさん:2008/09/06(土) 08:24:58
>>754
なにかを格納するって意味でのただのコンテナならいっぱいある
stlコンテナのことだったら、サイズ固定な時点で定義を外れるので存在しない
757デフォルトの名無しさん:2008/09/06(土) 08:43:28
>>755
すまん書き忘れた。
コンパイル時点ではサイズが決まらないんだ。
std::vector<int> v(10);
みたいなかんじで使いたい。

>>756
そうか・・・



自作するしかないかな。
758デフォルトの名無しさん:2008/09/06(土) 08:46:01
>>757
ならboost::multi_array
759デフォルトの名無しさん:2008/09/06(土) 08:49:26
>>758
おお!
boost::multi_array<int, 1>ってことか!
ありがと!
760デフォルトの名無しさん:2008/09/06(土) 09:04:17
VC使ってるならautoexp.datに
boost::multi_array<*,1,*>{
children
(
#array
(
expr: $c.base_[$i],
size : $c.allocated_elements_
)
)
preview
(
#(
"[",
$c.extent_list_.elems[0],
"](",
#array
(
expr : $c.base_[$i],
size : $c.allocated_elements_
),
")"
)
)
}
でも書いておくとデバッグ時に配列みたいに表示してくれる
上のはmulti_array<int, 1>の場合だけだけど
761デフォルトの名無しさん:2008/09/06(土) 11:45:01
const std::vector<T>だと都合が悪いんだろうな。
762デフォルトの名無しさん:2008/09/06(土) 15:21:36
>>760
すげぇ。

>>761
std::vectorだとメモリが倍々で確保されることが多いと聞いたので。

763デフォルトの名無しさん:2008/09/06(土) 15:34:15
>>762
作った時点で大きさ決まってて、その後リサイズしないならメモリの問題はないでしょ。
764デフォルトの名無しさん:2008/09/06(土) 15:44:07
そもそも倍々には確保されないと思うけどね。
765デフォルトの名無しさん:2008/09/06(土) 17:59:08
1.5 倍がいいらしいよ。
766デフォルトの名無しさん:2008/09/06(土) 18:00:06
大概倍々だよ
push_backで容量こえたからって、一個増やして再確保とかははまずやらない
767デフォルトの名無しさん:2008/09/06(土) 18:11:50
少なくとも要素数に比例させて再確保しないと償却定数時間の要件が満たせない。
単純に倍にするのが素直な実装。
768デフォルトの名無しさん:2008/09/06(土) 18:53:28
VCは1.5倍だm9
769デフォルトの名無しさん:2008/09/06(土) 19:50:20
どのVCだよ
770デフォルトの名無しさん:2008/09/06(土) 19:54:33
普通2のn乗サイズじゃね
771デフォルトの名無しさん:2008/09/06(土) 19:55:36
VC++2005で試してみた

void f(){
  std::vector<int> s;
  std::size_t c=0;
  for(int i=0; i<256; i++){
    s.push_back(i);
    if(c!=s.capacity()){
      c = s.capacity();
      std::cout << "c=" << c << std::endl;
    }
  }
}
-------------------------
c=1
c=2
c=3
c=4
c=6
c=9
c=13
c=19
c=28
c=42
c=63
c=94
c=141
c=211
c=316
772デフォルトの名無しさん:2008/09/06(土) 19:58:09
>>770
だから、0から順にpush_back()する場合は2倍にすると申し上げてますでしょう。
最初からサイズを指定していれば、2の冪乗になるとは限りませんってば。
773771:2008/09/06(土) 20:05:09
gcc3.4.6で試してみた

c=1
c=2
c=4
c=8
c=16
c=32
c=64
c=128
c=256
774デフォルトの名無しさん:2008/09/06(土) 20:07:20
mingw(gcc 4.1.2)の結果を貼ろうと思ったら>>773に先を越された
ちなみに同じ結果だったわ
775771:2008/09/06(土) 20:13:15
C# 2005の場合(System.Collections.Generic.List)
c=4
c=8
c=16
c=32
c=64
c=128
c=256

ちなみにjava6(java.util.ArrayList)はVC++2005同様に1.5倍

実装者の好みって感じなんだろうかね
776デフォルトの名無しさん:2008/09/06(土) 20:37:18
言語が違うとはいえ、
同じMS製のVC++とC#で違うのか・・・。
777デフォルトの名無しさん:2008/09/06(土) 21:04:20
M$だし…
778デフォルトの名無しさん:2008/09/06(土) 21:31:31
アンチもここまでくるとただのアホだな
779デフォルトの名無しさん:2008/09/06(土) 22:10:49
たしかにM$をただ非難するプログラマーは思慮が足りないように思う
経済的な効率を考えるとM$の製品の品質は感慨深いものがある
ユーザーとしてもう少し品質を高めて欲しい気もわからんでもないが
780デフォルトの名無しさん:2008/09/06(土) 22:44:40
struct drawable
{
    virtual void draw()=0;
};
class charactor :public drawable
{
    ...
};

こういう風に継承することで特定のメンバ関数の実装を強制する小さいクラスって何て呼ぶんだっけ?
781デフォルトの名無しさん:2008/09/06(土) 22:45:13
仮想クラス
782デフォルトの名無しさん:2008/09/06(土) 22:48:37
インターフェースクラスとか?
783デフォルトの名無しさん:2008/09/06(土) 22:54:42
抽象クラス
784デフォルトの名無しさん:2008/09/06(土) 22:57:07
抽象基底クラス
785780:2008/09/06(土) 23:15:26
ポリシーみたいな特別な呼び名があったと思ったんだが勘違いだったみたいだな
786デフォルトの名無しさん:2008/09/06(土) 23:33:42
一言で言うならインターフェイス

コンセプトは別物です
787デフォルトの名無しさん:2008/09/07(日) 00:50:31
C++なら抽象クラスと呼ぶこと多い気がするな
関数は純粋仮想関数

まぁ、Javaだと全てが仮想関数だしな・・・
788デフォルトの名無しさん:2008/09/07(日) 01:20:42
抽象クラスってのは抽象関数(純粋仮想関数)を持っているクラスのことで、
インターフェイスは抽象クラスのうち全ての関数が抽象関数で実装を持たないクラスのこと、
だと思う。
789デフォルトの名無しさん:2008/09/07(日) 02:24:45
インターフェースと呼ぶとオーバーヘッドなさそうに聞こえちゃうから
C++の場合は純粋抽象クラスとでも呼んだ方がいいと思うけどな
790デフォルトの名無しさん:2008/09/07(日) 03:28:51
プロトコルって言い方も何かね…
791デフォルトの名無しさん:2008/09/07(日) 03:49:06
インタフェースってのはライブラリの公開関数やクラスの一群を指す事もあるから
抽象クラスの方が明確かな
792デフォルトの名無しさん:2008/09/07(日) 12:50:12
行列計算に普段はmatlabを使っているのですが、loopが避けられない計算を
C++で書き直して計算させようとしてるとこです。

行列が128*128の時はmatlabに比べて30倍ほど速いのですが、実際に扱い
たい行列1024*1024の時はmatlabと比べて2倍程度にしか速くなりません。

行列の計算自体はドット積です。

大きな行列でもどうしたら速くできますでしょうか?

CPUはインテルのクアドコア3.2GHz、メモリ8G、インテルコンパイラ、OpenMP、行列処理にBlitz++使ってます。
793デフォルトの名無しさん:2008/09/07(日) 12:58:49
それはもはやC++の範囲を超えるんでねーの。
キャッシュに乗り切らないから遅いとか。
794デフォルトの名無しさん:2008/09/07(日) 12:59:44
手動で計算すればいいんだよ
795792:2008/09/07(日) 13:12:51
キャッシュがやっぱり関係してるんですかね。
Blitz++と比べてIntel Math Kernel Library使ったら速くなりますか?
796デフォルトの名無しさん:2008/09/07(日) 13:13:25
>>792
プロファイルとってみれば?

おそらく、ドット積を普通に計算すると行列全体に満遍なくアクセスするから
メモリキャッシュのヒット率さがってるんじゃないかな。
797デフォルトの名無しさん:2008/09/07(日) 13:22:50
doubleとfloatならfloatのほうが高速
798デフォルトの名無しさん:2008/09/07(日) 13:56:55
>>797
ある環境ではそうだったんだろうけど、環境が変われば結果も変わる可能性がある。
結局、速度は実測が基本。
799792:2008/09/07(日) 14:11:08
>>796
今目の前に居ないので分からないですが、行列のサイズを試しに512*512にしてみたところ一気にパフォーマンスが落ちたので、その通りだと思います。

floatでも試しに計算してみましたが、1024*1024ならdoubleとほとんどか
わり無しでした。

やはり2x6MBのメモリキャッシュがボトルネックみたいです。
大きなサイズの行列でキャッシュを有効に使う方法があれば教えていただける
とありがたいです。
800デフォルトの名無しさん:2008/09/07(日) 14:30:41
両者の実装に比べキャッシュがふんだんにありFPUの処理にfloatもdoubleも差がなければどちらも同じ。
801デフォルトの名無しさん:2008/09/07(日) 15:13:28
メモリのアクセス速度と実数演算速度が重要ならIntelのCoreより
AthlonX2のようなメモリコントローラを内蔵したCPUでFPUも強い
奴を積んでる物の方が多分速いよ

ベンチマークを取ってないからわからんけどクラスタサーバはCoreでは
なくて大抵Opteronで組まれてるし

単に値段が安いだけからかもしれんけど
802デフォルトの名無しさん:2008/09/07(日) 15:41:39
何の参考にもならんな
803デフォルトの名無しさん:2008/09/07(日) 15:43:26
Core信者乙
804デフォルトの名無しさん:2008/09/07(日) 15:45:10
ハードウェアの限界や特性はどうやったって越えられんわな
805デフォルトの名無しさん:2008/09/07(日) 17:32:38
floatで速度が変わらないように見えるのは、恐らくは型変換が入ってdoubleで計算している所為だろう。
例えば、うっかり2で割る積もりでa * b / 2.0なんて書いたらa * bもdoubleで行なわれてしまう。
806デフォルトの名無しさん:2008/09/07(日) 17:51:53
普通にdoubleの方が速いと思ってた俺
807デフォルトの名無しさん:2008/09/07(日) 18:02:37
速いかどうかはともかく普通はdouble使っておけばいいぞ。
速度が気になる事態になってから初めてfloatと比べればいい。
808デフォルトの名無しさん:2008/09/07(日) 18:04:19
floatってintと同じサイズでなんだっけ?
double floatはintの倍サイズじゃなくて、floatの倍精度ってことだよな?

すごいアホらしい話だが
809デフォルトの名無しさん:2008/09/07(日) 18:08:25
>>808
1. floatとintの大きさが同じとは限らない。
2. doubleはfloatの倍という意味での命名だが、倍になっていなくても規格に適合する実装は可能。
ただIEEE 754がすっかり定着しているけど。
810デフォルトの名無しさん:2008/09/07(日) 18:46:55
Blitzってマルチコア対応してくれるんだっけ
811デフォルトの名無しさん:2008/09/07(日) 19:52:42
規格上はfloatが0〜255の整数しか表せなくても何ら問題ないし
doubleがfloatより小さくても全く構わない

だから何だという話だが
812デフォルトの名無しさん:2008/09/07(日) 20:19:39
>>811
double が float より小さいのは明らかに規格違反。 (3.9.1 Fundamental types p8)
float の値の範囲については C の規格の FLT_MAX が 1E+37 以上でなければならないことに
なっていて、 C++ もそれに沿うことになる。
813デフォルトの名無しさん:2008/09/07(日) 20:29:13
811じゃないが、ちゃんと範囲まで定義されているとは知らなかった。
仮数部に関しては定義はされているの?
814デフォルトの名無しさん:2008/09/07(日) 20:42:45
>>813
numelic_limits の digits10 (Number of base 10 digits that can be represented without change) に
あたる FLT_DIG が 6 以上、 DBL_DIG が 10 以上じゃないといけないらしい。

http://www.open-std.org/jtc1/sc22/wg14/
"documents" > "Prei Santa Clara 2008 mailing" > "N1336"
5.2.4.2.2 Characteristics of floating types
815デフォルトの名無しさん:2008/09/07(日) 21:46:23
へー一応決まってるのね
char=1バイト以外は何も決まってなくてやりたい放題だと思ってた
816デフォルトの名無しさん:2008/09/07(日) 21:47:32
INT_MAX >= 32767とか整数型もある程度の縛りはあるよ。
817デフォルトの名無しさん:2008/09/07(日) 22:01:41
>>814
つーことは、符号もあわせると最低17bit必要ってことか。
818デフォルトの名無しさん:2008/09/07(日) 22:12:20
普段、float型は使わない主義だから、そこまで考えたことないなー
必須になるのって画像処理とか円周率使うときくらいかな
819デフォルトの名無しさん:2008/09/07(日) 22:20:37
まあ実際問題FPU使う99.9%の問題はdouble使っとけば問題ない。
よっぽどでかい配列使うとかSIMD視野に入れて最適化が必要な場合以外は。
820デフォルトの名無しさん:2008/09/07(日) 22:24:41
いくら規格規格言っても「違反」な実装を使わないわけにもいかない
821デフォルトの名無しさん:2008/09/07(日) 22:30:10
>>820 屑コンパイラメーカー乙
822デフォルトの名無しさん:2008/09/07(日) 23:09:06
>>821
組み込みなんかだと浮動小数点とかいらなかったりしないか?
823デフォルトの名無しさん:2008/09/07(日) 23:13:19
C言語 フリースタンディング
でぐぐれ
824デフォルトの名無しさん:2008/09/07(日) 23:15:50
>>822
そんなターゲットもあるだろうけど、だから何だというの?
コンパイラメーカーの決めることじゃないだろ。
825デフォルトの名無しさん:2008/09/07(日) 23:30:09
>>822
コピーするときに浮動小数点レジスタ使うこともある
826デフォルトの名無しさん:2008/09/08(月) 01:21:35
それはC++ではなく、アセンブラのテクでは?
827デフォルトの名無しさん:2008/09/09(火) 23:03:15
実現したい機能がリフレクションを使わないと書けないかめんどくさい
・Type.getType()相当のプリミティブ
・Invoke()相当のプリミティブ
 があれば文字列をえっちらおっちらこさえれば.NET Frameworkのコードが呼べるはず。
 これならスタック二段増えるだけなので手間じゃないはず。(文字列こさえるのはともかくとしてね……)
 大本のプリミティブの下に積んでやれば下位互換性も保たれる。
828デフォルトの名無しさん:2008/09/10(水) 07:04:28
C/C++はD言語に取って代わられるときがくるのでしょうか
829デフォルトの名無しさん:2008/09/10(水) 07:20:18
テンプレートの書き方(宣言&実装)の質問です。

今までテンプレートを自分で書いたことがなかったので、試しに今までクラスで書いていた
コードに手を加えてテンプレートクラス化してみて気づいたのですが、クラスと違って
テンプレートの実装は宣言とは別に書くことってできないみたいですね。
(コンパイル時にテンプレートにはまる型が決まらないといけないのだと理解しました)

というわけで宣言と実装をヘッダーでやればいんでしょうけど、そうすると関数の一覧が
見えにくいような気がするんですが.... そんなもんでしょうか?
もしかして分けて書く方法もあったりします?
830デフォルトの名無しさん:2008/09/10(水) 07:46:11
言葉のあやなんだろうけど、定義と宣言を分けること自体はできる
同じファイルでだが

ファイルを分けてそれぞれコンパイル、という意味で分けるというのなら確かにできない
理由はあなたが言った通り
831デフォルトの名無しさん:2008/09/10(水) 07:47:03
あぁ同じファイルってのは正しくないか・・・翻訳単位だっけ・・?
832デフォルトの名無しさん:2008/09/10(水) 07:59:28
>>830
>言葉のあやなんだろうけど、定義と宣言を分けること自体はできる

あ、もしかして単純に一個のファイルになってたらいいですかね?
一つのファイルの前半が宣言、後半が実装みたいな。
だったらヘッダファイルの後半で #include "hogehoge.cpp"みたいにすればファイル分割
も一応可能、みたいな。
833デフォルトの名無しさん:2008/09/10(水) 08:39:10
>>832
#includeでの埋め込みはコンパイル前なので確かにできます

でもそもそもクラス宣言があると関数一覧が見えにくいというのがよく解からんが
834デフォルトの名無しさん:2008/09/10(水) 08:53:47
インラインだったらヘッダーから.inlファイルをインクルードってのはよく見るが
テンプレートでも.inlファイルって使うのかな
835デフォルトの名無しさん:2008/09/10(水) 09:00:55
>>833
>#includeでの埋め込みはコンパイル前なので確かにできます

確かに、試してみたらよさげです。

>でもそもそもクラス宣言があると関数一覧が見えにくいというのがよく解からんが

テンプレートに限らず普通にクラスを定義するとき、
メンバ関数の宣言と実装を一緒に書く方式(ってもしかして意味不明ですか? もっと標準
的な言い方があったら教えてください)で全部書くと、
そのファイルでメンバ関数の一覧だけ参照したいとき、見にくくないですか? という程度の
ことなんですが...
836デフォルトの名無しさん:2008/09/10(水) 09:28:56
一緒に書くのが見にくいなら、分けて書けばいいだけじゃん
ヘッダファイル内で分けて書いていけない理由はない
837デフォルトの名無しさん:2008/09/10(水) 09:49:20
どっちでもいい。
俺はdoxygen用のコメントでうざくなるから分けて書くが
838デフォルトの名無しさん:2008/09/10(水) 11:28:26
exportというキーワードで翻訳単位をコントロールできるコンパイラもあるみたいですね。
839デフォルトの名無しさん:2008/09/10(水) 13:47:31
void f(const char* a[]){}

char *arr[30];
を渡すと
引数を 'char *[30]' から 'const char *[]' に変換できません。(新しい機能 ; ヘルプを参照)
というエラーが出ます.

char *からconst char*なら暗黙に変換してくれると思うんですがなぜでしょうか




840839:2008/09/10(水) 13:48:27
>>839
環境はvc++ 2008です
841デフォルトの名無しさん:2008/09/10(水) 13:53:16
stringを使ってください。無駄な作業が減らせます。
842デフォルトの名無しさん:2008/09/10(水) 13:53:26
constはどこにかかってると思う?
843デフォルトの名無しさん:2008/09/10(水) 14:01:45
>>841
腑に落ちないもので...すみません
>>842
変更できない文字,へのポインタ,の配列
が仮引数だと思っていますがあっていますか?
844デフォルトの名無しさん:2008/09/10(水) 14:34:16
説明するのも困難というのは考えものだな、いいかげんこの言語は消滅すればいいと思う
void f(const char* a[]){}
const char *arr[30];
f(arr);
とするか
char *arr[30];
void f(char* const a[]){}
f(arr);
とすると通るんだな、んでどこがconstかというとポインタという事なんだが、一応C++の規則どおりな訳ですが・・・
おれなんかはオーバーロードして
void f(const char* a[]){}
void f(char* a[]){}
reinterpret_cast でやるか template を使ったりと
845デフォルトの名無しさん:2008/09/10(水) 14:38:20
おっと、どこの const が自動キャストかというとポインタの事
const char は char の const
間違いを指摘したような文書になってしまった
846839:2008/09/10(水) 14:40:45
どうも混乱しているのですが
f()はaを介して値が変更されない事を前提にしているので,
変更することのできるarrを受け取るわけにはいかない,ことは納得しました.
スレ汚しすみません
847839:2008/09/10(水) 14:44:48
>>844
>>845
すれ違いになってしまいました.
なかなか頭に入ってこないのでゆっくり考えてみます.

848デフォルトの名無しさん:2008/09/10(水) 14:45:53
typedef してみるとわかりやすいかもね
typedef const char * cp_char;
void f(cp_char a[]) {}
cp_char arr[30];
f(arr);
const が自動でついたり外れたりするのは、以下のの位置
void f(const cp_char a[]) {}
const cp_char arr[30];
f(arr);
んで、この const は元々どこだよというと
void f(char * const a[]) {}
char * const arr[30];
f(arr);
死ねるw
849デフォルトの名無しさん:2008/09/10(水) 14:49:46
あぁ、そうそう、これも C プロトタイプの分かりにくい点の一つ
const char と char const は、同じ型、最初の宣言は互換のためで、これだけ規則が例外だ!!
const は左側を修飾するから、
char const * const a[]
といった書き方にしたら見通しがいいかも知れない。
850839:2008/09/10(水) 15:07:55
ftp://sunsite.unc.edu/pub/Linux/devel/lang/c/
からcdeclとか言うプログラムを落として使ってみたところ,
宣言の違いはよく分かりました.

(1) const char *a[];
declare  as array of pointer to const char;
(2) char * const a[];
declare  as array of const pointer to char;

f()の中で
a[0] = ...;
という処理を行っているので2番目の書き方はできなさそうです.

元々
char arr[30];
const char arr[30];
のどちらでも引数とできる関数を作りたかったのですが,
仮引数は(1)も(2)も駄目で結局
void f(char*a[]){}
とするか>>844さんのようにオーバーロードするしかなさそうです.

>>849 さんのものはなじみが薄いのですが
char const * const a[];
declare  as array of const pointer to char const;
と言う事なので恒久的に変化しない文字列配列に使用するのでしょうか.
851839:2008/09/10(水) 15:09:57
>>850 *が抜けていました
char *arr[30];
const char *arr[30];
852デフォルトの名無しさん:2008/09/10(水) 15:53:52
char const * const p;
const char * const p; // アドレスもデータも変更できない。
const char * p; // データは変更できないが、アドレスは変更できる。
char * const p; // アドレスは変更できないが、データは変更できる。
char * p; // アドレスもデータも変更できる。

Effective C++
853デフォルトの名無しさん:2008/09/10(水) 16:01:02
どっかにcdeclのWindowsでも動く版ないかなぁ
854デフォルトの名無しさん:2008/09/10(水) 20:49:40
>>828
DがGCを捨てると決意するまでは絶対にない

GCを持つ言語がC/C++に取って代わることは永遠にないよ
用途によって部分的に置き換わることはあっても
855デフォルトの名無しさん:2008/09/10(水) 21:22:03
doubleの計算結果がNaNかどうかって、どうやって判別すればいいんでしたっけ?
移植性がある答えをおながいします
856デフォルトの名無しさん:2008/09/10(水) 21:30:53
>>855
どの程度の移植性かが微妙だけど標準に沿えとかいうんじゃむり

ieee754なら直接ビット見れば判定できるよ
857デフォルトの名無しさん:2008/09/10(水) 21:34:03
>>856

VCであれば_isnanを使えばいいようですが、
インテルコンパイラの場合どうするんでしたっけ。
858デフォルトの名無しさん:2008/09/10(水) 21:41:23
class CHoge{
public:
std::string m_str;

CHoge(){m_str.empty();}
void addText(std::string str){m_str+=str;}
void print(){cout << m_str.c_str() << endl;}
};

void SetStr(CHoge* hoge){
std::string bar= "ponyo";
hoge->addText(bar);
}

void main(){
CHoge* hoge = new CHoge;
SetStr(hoge);
hoge->print();
}

これって正しいですか?
SetStrの std::string bar = "ponyo";
のSetStrを出た後の生存期間とかで問題は起きませんか?

一応、この単純なプログラムは正常に動作している(ように見える)のですが
別のもっと複雑なアプリで同じような部分で問題がおきていて、
生存範囲の問題なのかなぁとか思って
上記のように単純に切り出して再現してみたところ上手くいってしまいまして・・・
でもたまたま上手くいってるという場合も考えられるので・・・
どうでしょうか。教えて下さい。

環境はVS2005です。
859デフォルトの名無しさん:2008/09/10(水) 21:44:02
とりあえず。。。
CHoge(){m_str.empty();}

CHoge(){m_str.clear();}
じゃないの??
emptyは空かどうかを調べるだけのメソッドだし。
正直stringクラスのデフォルトコンストラクタで空文字になるから、
m_str.clear()も入れる必要ないけど。
860デフォルトの名無しさん:2008/09/10(水) 21:45:27
clearじゃなくてeraseだった
861デフォルトの名無しさん:2008/09/10(水) 22:21:37
>>859-860
すいません、勘違いしておりました。

それで、、、本題の方はどうなんでしょうか?
862デフォルトの名無しさん:2008/09/10(水) 22:25:23
>>854
でも、C++0xでもGCを実装しやすくするための機構が導入されるんでしょ?
863デフォルトの名無しさん:2008/09/10(水) 22:28:11
>>862
「でも」はおかしいだろ。
864858:2008/09/10(水) 22:40:54
問題は全く別な場所でした・・・
すいません。ひとまずそこを直したら上手く動いたようです。
865デフォルトの名無しさん:2008/09/10(水) 23:08:32
>864
一応補足しておくと addText は値渡し、つまりコピーして引数を渡しているので問題は発生しない。
866デフォルトの名無しさん:2008/09/10(水) 23:43:32
>>862
DはGCを常に使うことが出来、C++0xはGCを使うことも出来る。
ゆえにDのライブラリは常にGC前提で書くことが出来、
C++のライブラリはGCを前提とすることと汎用性がトレードオフになってしまう。

しかし逆にDはGCのメリットと共にデメリットも常に持つことになり、
C++ではGCのメリットを十分に享受出来ないとしても、
デメリットを排除出来ることを重要視している。

まぁGCもかなり進歩してるし、設計思想の違いってところだろうけどな。
GCだけが理由じゃないだろうけど、その辺のために
Dが使われることが増えてきたとしても置き換わる事は無いだろう。
867デフォルトの名無しさん:2008/09/11(木) 03:06:25
現実的には無い
868デフォルトの名無しさん:2008/09/11(木) 03:12:50
NaN判定を(x!=x)で行えるのは実装依存?
869デフォルトの名無しさん:2008/09/11(木) 03:18:16
>>868
はい、そうです。
870デフォルトの名無しさん:2008/09/11(木) 08:53:05
extern "C"について質問があります。

リンクエラーを解消するために、
mainが書いてある*cppファイルのヘッダすべてにextern "C"をつけました。
ヘッダには、ほかの*.cファイルの関数の定義が書いてあります。

これでうまく動くとおもったんですが、まだリンクエラーが取れません。
*.libも全部リンクしてあるし、原因がわかりません。

他になにかこのエラーが出る原因ってありますか?
871デフォルトの名無しさん:2008/09/11(木) 08:56:26
cppに定義がないとか普通のリンクエラーだったらextern "C"とか意味ないと思うが
872デフォルトの名無しさん:2008/09/11(木) 08:59:42
>>870
とりあえずエラーはってくれよ
873デフォルトの名無しさん:2008/09/11(木) 09:06:51
エラー 46 error LNK2019: 未解決の外部シンボル _fatal_error が関数 _import_oxfd_features で参照されました。 imgfeatures.obj
エラー 47 error LNK2001: 外部シンボル "_fatal_error" は未解決です。 dspfeat.obj
エラー 48 error LNK2001: 外部シンボル "_fatal_error" は未解決です。 sift.obj
エラー 49 error LNK2001: 外部シンボル "_fatal_error" は未解決です。 xform.obj
エラー 50 error LNK2019: 未解決の外部シンボル _gsl_rng_free が関数 _ransac_xform で参照されました。 xform.obj

こんなのがでてます…
874デフォルトの名無しさん:2008/09/11(木) 09:36:29
リンクするライブラリが足りないんだろ
875デフォルトの名無しさん:2008/09/11(木) 10:19:32
自分で作った関数がないって言われてるのか?
リンクする前の.oをobjdumpしてちゃんとシンボル名が合ってるか確認してみ
876デフォルトの名無しさん:2008/09/11(木) 10:55:09
ちょっとGSL探してきたが、すくなくともgsl_rng_free はgsl.libに入ってるな。
877デフォルトの名無しさん:2008/09/11(木) 10:58:06
あと、fatal_errorは自前のものなんだろうけど、cppで定義してるのにextern "C"つけちゃってみつからないんじゃないのか?
わけもわからずにやってるんじゃないか。
878デフォルトの名無しさん:2008/09/11(木) 12:35:52
>875
関数は全部自分でつくったやつです。
mainの入ってるのが*.cppで
のこりは全部*.cです。
いろいろと定義してあるヘッダファイルを*.cppの中で
extern "C"{ } しています。
>876
objdumpというのは初めてききました。探してみます。
>877
間違ってるかもしれませんが、cppだとふyじこlp@関数名というふうに自動でリネームするので、
そうならないようにextern"C"をつけてcの関数を読み込むんだということを調べました。
879デフォルトの名無しさん:2008/09/11(木) 12:41:55
>>878
だからよ、_fatal_errorのような、先頭がアンダースコアなのはextern "C"してるってことだが
fatal_errorの実体はextern "C"してないんじゃないかってことだ。
具体的には、fatal_errorというグローバル変数がどこかにあって、
ヘッダファイルで extern "C" 付きで extern宣言してるんじゃないかってこと。
880878:2008/09/11(木) 15:52:19
みなさん、レス下さってありがとうございます。
解決できました。
VisualStudioの設定でlibを追加したり***.hを*.cに書き込んだりしたら動きました。
881デフォルトの名無しさん:2008/09/11(木) 17:47:37
最近 typeid なる機能の存在を知ったのですが、あまりこれを使ったソースを
見かけません。何か問題あるんでしょうか? 
それとも、たまたま私が遭遇してないだけ?
882デフォルトの名無しさん:2008/09/11(木) 17:48:03
使い道がないだけ
883デフォルトの名無しさん:2008/09/11(木) 18:33:25
デバッグ用にクラスの名前出力するのに使った事はあるな。
884デフォルトの名無しさん:2008/09/11(木) 18:37:56
boost::anyあたりで使われてた気がする
885デフォルトの名無しさん:2008/09/11(木) 19:24:53
そういうことか。ありがとー
886デフォルトの名無しさん:2008/09/11(木) 19:24:59
メタプログラミングのデバッグにはとても便利だぞ。
ただ、gccのname()で返される文字列が、とてもhuman readableとは思えないが。
MSVCなら分かりやすい。
887デフォルトの名無しさん:2008/09/11(木) 21:46:15
std::vector<double> valueList;
の数値のリストがあって、

ある数 t が与えられたときに
t が valueList の中で何番目に小さな数字か
ってのを求めたいんだが、
エレガントにやるにはどうしたらいい?



って相談されたんだがどうすればいい?
888デフォルトの名無しさん:2008/09/11(木) 21:47:48
ググレカス
889デフォルトの名無しさん:2008/09/11(木) 23:06:19
>>887
count_ifでtより小さい要素の数を数えるとか。
890デフォルトの名無しさん:2008/09/11(木) 23:35:05
>>887
nth_elementはどう?
891デフォルトの名無しさん:2008/09/11(木) 23:52:51
>>889,890
とんくす
892デフォルトの名無しさん:2008/09/12(金) 00:18:40
>>887
何したいかによるが場合によってはvectorじゃなくてmultisetとか使ったほうがいい気がする
893デフォルトの名無しさん:2008/09/12(金) 07:41:01
valueListが最初に構築されたあと要素が変化しないなら、ソート済みvectorで二分探索もあるね。
tが何番目に小さいか、何回も求めるならこれが最速じゃないかな。
894デフォルトの名無しさん:2008/09/13(土) 22:06:50
関数内 static 変数の初期化について

struct Foo
{
Foo() { /* 初期化処理 */ }
};

int hoge()
{
static Foo foo;
// do something...
return 0;
}

関数 hoge() が初めて呼び出された直後に、別のスレッドからも hoge() が呼び出された場合、
クラス Foo のコンストラクタが一回しか実行されないことは保証されるのでしょうか?

初期化の実装が

bool foo_is_constructed = false;
int hoge()
{
if (foo_is_constructed == false)
{
foo_is_constructed = true;
// Foo foo; のコンストラクタ呼び出し
}
return 0;
}

みたいになってたらまずいと思うのですが。。。
しかもアセンブリ吐かせて眺めた限りではそんな気がします。。。
895デフォルトの名無しさん:2008/09/13(土) 22:45:34
マルチスレッド/コア絡みの安全性保証は、
コンパイラにオプションがあって、かつ、ユーザがそれを指定しない限り
全くされないと思ったほうがよい

スレッド間の同期というのは、システムによっては数千クロック以上の
ペナルティがかかることもあるぐらい、かなり重たい処理なのです
コアが違うとキャッシュなんかも、からんできますからね

だから、勝手にそんなことをされたら、性能が落ちるから、
原則止めましょうというのがC/C++系の思想と思います
896デフォルトの名無しさん:2008/09/13(土) 23:01:46
Singletonパターンでぐぐるとその手の議論は山ほど出てくるよ
897デフォルトの名無しさん:2008/09/13(土) 23:51:16
>>895
なるほど。マルチスレッド・マルチコアがらみはユーザ・ライブラリ側で調整するべきと言うことですね。
そもそも C++ にはスレッドという概念がありませんでした。。。

>>896
勉強になります。Java では二重チェックしてもうまく働かなかったりするらしいですね。おそろしや〜


せっかくなのでマクロを考えてみました (C99 と BOOST がごっちゃになってますが)

#define STATIC_VARIABLE(type, name, ...) \
static boost::shared_ptr<type> p_##name;\
if (!p_##name)\
{\
static long l = 0;\
if (BOOST_INTERLOCKED_INCREMENT(&l) == 1) p_##name.reset(new type(__VA_ARGS__));\
}\
type &name = *p_##name

いや、こりゃだめだ
898デフォルトの名無しさん:2008/09/13(土) 23:52:03
めんどくさいから関数の頭でスピンロックでいいよもう
899デフォルトの名無しさん:2008/09/14(日) 00:48:52
>>898
つまりこういうことですか

class SpinLock
{
public:
SpinLock() { while (locked || InterlockedExchange(&locked, 1)) { } }
~SpinLock() { InterlockedExchange(&locked, 0); }
private:
static long locked;
};

long SpinLock::locked = 0;

int foo()
{
SpinLock sl;
// do something
return 0;
}

while (...) { } のあたりがスピンです
900デフォルトの名無しさん:2008/09/14(日) 07:59:42
やればできるじゃないか!
901デフォルトの名無しさん:2008/09/14(日) 08:16:44
それスピンロックになってねーよ。
lockedのテストとInterlockedの呼び出しの間に別スレッドに簡単に割り込まれるじゃん。
何のためにInterlockedCompareExchangeがあると思ってるんだよ。
902デフォルトの名無しさん:2008/09/14(日) 08:26:32
まあその手の話題はもっと適切なスレでも普通に話題になってるよ。
http://pc11.2ch.net/test/read.cgi/tech/1187008532/850-858
とかね。読めないかもしれないが。
903デフォルトの名無しさん:2008/09/14(日) 08:45:01
K主任ってどのスレだったっけ
904デフォルトの名無しさん:2008/09/14(日) 10:45:10
スレッド生成する前に、static変数を使用して初期化すればいいんじゃないの
905デフォルトの名無しさん:2008/09/14(日) 13:31:05
a
906デフォルトの名無しさん:2008/09/14(日) 14:34:23
>>901
すみませんでしt。
907デフォルトの名無しさん:2008/09/14(日) 17:25:05
std::vector<double> data(1000000)というvectorがあったとき、各要素を一つずつ+=しながら
合計を出すのとは別の方法はありますか?オーバーフローは考えなくてかまいません。
・シンプルなコード
・高速なコード
のどちらかを期待しています。両方かなえばうれしいです。
908z169.219-103-218.ppp.wakwak.ne.jp :2008/09/14(日) 17:29:57
誤差も考えなくて良いの?
909デフォルトの名無しさん:2008/09/14(日) 17:31:12
std::accumulate
910デフォルトの名無しさん:2008/09/14(日) 17:36:24
スレッドを使う。 もし、2桁増えて800Mぐらいだったら
いったんHDDに保存しておいて10Mずつ位読み込んで足す。
HDD(仮想メモリ)に連続アクセスするより確実にメモリに乗っていた方が読み込みが速い
911907:2008/09/14(日) 18:00:13
>>909
素晴らしい。やはりこのようなものがあったのですね。

>>908
すみません、誤差も考えなくて良いです。
数値解析の元ネタにするもので、有効桁数6桁くらいで大丈夫です。

>>910
なるほど、スレッドですか。ちょっと試してみます。

すばやい回答、ありがとうございました。
912デフォルトの名無しさん:2008/09/14(日) 18:15:15
メモリアクセスが最大のボトルネックだから、
複スレッド化しても必ずしも速くなるとは限らんよ。
プロセッサの得手不得手が出るところでもあるから、
あるプロセッサで測って最速なのが他でもそうだとも限らない。
913デフォルトの名無しさん:2008/09/14(日) 18:17:59
このケースではstd::accumulateが一番だろうな
914デフォルトの名無しさん:2008/09/14(日) 18:20:31
1ギガ近くの配列ならいちど解放した方が速いと思うよ。
うちのPCはメモリ512Mだから、1ギガ確保するとOSが不安定になって相当掛かる。
915デフォルトの名無しさん:2008/09/14(日) 18:23:34
double*1000000なら8GBくらいじゃねえの。
そんなもんverctorで持つなよw
916デフォルトの名無しさん:2008/09/14(日) 19:10:04
いやたかだか1000000個だぞ? doubleがどんだけでかいと思ってんだ?
917907:2008/09/14(日) 19:15:21
なんだか誤解を与えるような書き方になってしまったようですが、個数は例ではなくて実数でした。
一度に処理するのが100万個なんです。
GBレベルの処理を考えてくださった方は申し訳ありませんでした。
918デフォルトの名無しさん:2008/09/14(日) 19:29:34
その位だったら迷わずstd::accumulate()一択。
919デフォルトの名無しさん:2008/09/14(日) 20:03:17
100万個じゃ24bitのHD解像度の画像処理するよりも少ないよな。
920デフォルトの名無しさん:2008/09/15(月) 23:49:01
921デフォルトの名無しさん:2008/09/15(月) 23:50:24
誤爆
922デフォルトの名無しさん:2008/09/19(金) 07:46:00
すみません、C -> Objective-C -> C++と経由して来た者ですが、C++で基底クラス
のメンバ関数を参照するときにはどうすべきか悩んでいます。

例えば基底クラスBaseClassにfoo()という関数があったとしてこれを派生クラス
DerivedClassのfoo()で拡張するとき、
DerivedClass::foo()
{
// まず基底クラスのfoo()を実行 --- (1)
// 次に独自の処理を実行 -- (2)
}
としたいのですが(1)はどう呼ぶべきでしょうか。Objective-Cだとsuperという予約語で
基底クラスを参照できたのですが。C++でそれに該当するものはないようですね。

とりあえずBaseClass::foo()と、スコープ解決演算子(ですよね?)を書けばよさげなんで
すが、ちょっと柔軟性に欠けるような気がしました(例えば基底クラスが変わったときとか、
クラスが何回層かになっている時とか)。
923デフォルトの名無しさん:2008/09/19(金) 08:02:58
柔軟性の問題ならtypedefで解決かなあ

そもそも関数名を同じにしなければ解決するんじゃない?
class super
{
 virtual void foo(){ bar(); }
 void bar(){ /* ... */ }
};

class sub : super
{
 void foo(){ bar(); /* ... */ }
};
とか。

C++で基底クラスを示す方法がないのは、多重継承を認めてるから
924デフォルトの名無しさん:2008/09/19(金) 08:03:50
あ、bar()のアクセス指定はもちろんprotectedかpublicね
925デフォルトの名無しさん:2008/09/19(金) 08:53:46
多重継承の時にエラーにすればいいだけだと思うけど、なんで標準にないんだろうね。
926デフォルトの名無しさん:2008/09/19(金) 09:39:40
cを
hoge.so
にしてpythonから呼んでるのですがsoをgdbでデバックするにはどうすればいいのでしょうか?
927デフォルトの名無しさん:2008/09/19(金) 10:05:19
>>925
D&Eの13.6 にこの機能が標準化委員会に提案され、却下された経緯が書いてある。
928デフォルトの名無しさん:2008/09/19(金) 15:56:26
特定のデータ型に対してテンプレート関数の挙動を変えたいとき、オーバーロードと特殊化のどちらを使うのが
よいのでしょうか?

// オーバーロード
template <class T> void foo(const T &) { }
void foo(const std::string &) { }

// 特殊化
template <class T> void foo(const T &) { }
template <> void foo<std::string>(const std::string &) { }
929デフォルトの名無しさん:2008/09/19(金) 15:58:39
普通は特殊化な気がするが
って言うかテンプレートのオーバーロードなんて考えたことなかったな
930デフォルトの名無しさん:2008/09/19(金) 16:03:39
確かに特殊化が普通の気はするのですが、オーバーロードを使えば

temlate <class T> void foo(const T &) { }
void foo (int) { } // int では値で受け取る

のような事ができるので、こちらも捨てがたいのです。
オーバーロードが一般的でないとすれば、何か理由があるのでしょうか?(部分特殊化の可否?)
931デフォルトの名無しさん:2008/09/19(金) 17:41:14
オーバーロードだと、オーバーロードされるテンプレートの存在を見落としてしまう可能性があるね。
特殊化だと、汎用テンプレートがあるよっ!って教えてくれるから読みやすいよな。
932デフォルトの名無しさん:2008/09/19(金) 18:52:29
>>931
確かに可読性という意味では、特殊化に分がありますね。

しかし

class Hoge { };
template <class T> void foo(const Hoge &, const T &) { }
template <class T> void foo(const T &, const Hoge &) { }

void bar() { foo(Hoge(), Hoge()); } // エラー! テンプレートの解決が曖昧

のような状況を考えれば(二項演算子をテンプレートにする場合など)、
オーバーロードも捨てられない気がします。
933デフォルトの名無しさん:2008/09/19(金) 19:11:55
templateクラスの中でテンプレートパラメータが決定してから判明する定数をマクロで使うことってできないですか

template<typename T>
class Hoge{
#if sizeof(T)==1
char piyo(){
return (char)T;
}
#endif
};

みたいな?
934デフォルトの名無しさん:2008/09/19(金) 19:28:29
>>933
プリプロセスはテンプレートの実体化より前に行われるからできないでしょ。
ていうかマクロ使ってないし。

どうしてもやりたければ

#include <boost/static_assert.hpp>

template <typename T>
class Hoge
{
public:
char piyo()
{
BOOST_STATIC_ASSERT(sizeof(T) == 1);
return reinterpret_cast<char>(*this);
}
};

みたいなことをすればいい。
でももっといいやり方があると思うよ。
935デフォルトの名無しさん:2008/09/19(金) 21:07:50
部分特殊化でいいんじゃないの?

template<typename T, std::size_t Size = sizeof(T)>
class Hoge { };

template<typename T>
class Hoge<T, 1>
{
char piyo() { return xxx; }
};
936デフォルトの名無しさん:2008/09/19(金) 23:50:37
「 int 型のイテレート可能な型を引数に取る関数」って定義できる?
多重定義したいので、型を丸々 template で受け取るってのは無しで。
937デフォルトの名無しさん:2008/09/19(金) 23:55:53
意味が分からん。
938デフォルトの名無しさん:2008/09/20(土) 00:18:25
>>936
void hoge(int *first, int *last);
void hoge(std::vector<int>::iterator first, std::vector<int>::iterator last);
void hoge(std::list<int>::iterator first, std::list<int>::iterator last);

...これをネタにもう少し詳しく。意味が分からん。
939デフォルトの名無しさん:2008/09/20(土) 01:52:37
言葉足らず過ぎでした。ごめんなさい。

void print( int i ) {
cout << i;
}

template<class T>
void print( const iterable<T>& xs ) {
for( const T& x : xs ) {
print( x );
}
}

この iterable のところを、 std::list なんかの具体的な方を書かずに実装できるのかな、という質問です。
940デフォルトの名無しさん:2008/09/20(土) 02:00:35
template<template<class> class A, class B> void f(A<B> x);

template<class T> class C {};

void g()
{
C<int> c;
f(c);
}
941デフォルトの名無しさん:2008/09/20(土) 02:12:28
duck-typingでおk
942デフォルトの名無しさん:2008/09/20(土) 04:53:33
>>928-932
いや、オーバーロードの方が一般的でしょう。

C++ Coding Standards 66項でも、
関数テンプレートの特殊化ではなく、
オーバーロードで解決する方が望ましいとしてる。
943デフォルトの名無しさん:2008/09/20(土) 04:57:47
きっとこういうことだと予想。無駄にTR1使ってみた。あと、おそらくremove_cvも使ったほうがよい。
#include <iostream>
#include <iterator>
#include <type_traits>
#include <array>
#include <boost/utility/enable_if.hpp>
template<typename Iter>
struct is_int_iterator : std::tr1::is_same<typename std::iterator_traits<Iter>::value_type, int> {};
template<typename Iter>
void f(Iter first, Iter last, typename boost::enable_if<typename is_int_iterator<Iter> >::type* = 0)
{
std::cout << "int" << std::endl;
}
template<typename Iter>
void f(Iter first, Iter last, typename boost::disable_if<typename is_int_iterator<Iter> >::type* = 0)
{
std::cout << "not int" << std::endl;
}
int main()
{
int i[5];
std::tr1::array<long, 3> l;
f(&i[0], &i[5]);
f(l.begin(), l.end());
}
944デフォルトの名無しさん:2008/09/20(土) 10:08:52
>>940
> template<template<class> class A, class B> void f(A<B> x);
の"template<class> class A"という書き方初めて見たけど、なんていうの?
945デフォルトの名無しさん:2008/09/20(土) 10:22:06
>>939
ずばりそんな書き方でできると思うんだがなにか問題があったのか?
946デフォルトの名無しさん:2008/09/20(土) 11:04:24
>>944
Template Template Parameter
まず使うことはないな。
947デフォルトの名無しさん:2008/09/20(土) 12:09:19
これコンパイル通らないんですけどどうしてですか?
operator<<が見つからないというエラーが出ます

#include <iostream>
template <template <class> class A, class B>
void f(A<B> x)
{
std::cout << x << std::endl;
}
template <class T>
class C {
T i;
public:
C(T c = 123) : i(c) {}
friend std::ostream& operator<<<T>(std::ostream& os, const C<T>& c);
};
template <class T>
std::ostream& operator<<<T>(std::ostream& os, const C<T>& c)
{
os << c.i;

return os;
}
void g()
{
C<int> c;
f(c);
}
int main()
{ g(); }
948デフォルトの名無しさん:2008/09/20(土) 12:41:46
俺特製コンパイラなら通るけど?
949デフォルトの名無しさん:2008/09/20(土) 12:56:06
済みませんいい忘れました。
コンパイラはMinGW (gcc 3.4.5) を使っています。
950デフォルトの名無しさん:2008/09/20(土) 13:13:30
>>947
mainに全角空白があるから
951デフォルトの名無しさん:2008/09/20(土) 13:23:06
>>940
こんな構文があるんですね。知らなかった。でも一引数のテンプレートクラス = コンテナとするにはちょっと乱暴かな…。

>>943
boost::mpl とか、つい避けてきたんですが、便利ですね。
( type* = 0 というテクニックすら初めて知りました…)
コンテナを受け取る関数は

template<class T> void f( const T& xs, T::const_iterator* = 0 );

とりあえずはこのくらいでも十分かな。

>>945
えっと、具体的にはどう書けばいいんでしょうか。
952デフォルトの名無しさん:2008/09/20(土) 13:55:21
>>950
おっしゃる意味がわかりません。
全角文字など使っていません。
953デフォルトの名無しさん:2008/09/20(土) 13:57:49
>>952
投稿した奴には空白混ざってるよ
まぁ除いてもコンパイルは通らないけど
954デフォルトの名無しさん:2008/09/20(土) 14:05:32
template <class T>
class C {
...
template<class U>
friend std::ostream& operator<<(std::ostream&, const C<U>&);
};

template <class T>
std::ostream& operator<<(std::ostream& os, const C<T>& c) {
...
}

もしくは

template<class T>
class C {
...
friend std::ostream& operator<<(std::ostream&, const C<T>&) {
...
}
};

若干意味が違うけど。
955デフォルトの名無しさん:2008/09/20(土) 14:06:23
>>953
そうですそのコンパイルが通らない理由を知りたいのです。
全角文字は投稿の際にもしかして混ざってしまったのかもしれませんが
ソースには入っておりません
956デフォルトの名無しさん:2008/09/20(土) 14:10:06
>>954
ありがとうございます。無事コンパイルが通りました。
957デフォルトの名無しさん:2008/09/20(土) 14:15:03
全角空白が元から入っていたのか、投稿時に紛れ込んだのかは
他の人には分からないよね。
そして、全角空白によってもコンパイルが通らないわけで。
だから、それに気が付いたすごく親切な人が親切に教えてくれたわけで。
一応、俺だったら礼はするな。
958デフォルトの名無しさん:2008/09/20(土) 14:18:29
はいはい、お前さんは礼儀正しいですね
959デフォルトの名無しさん:2008/09/20(土) 14:20:12
>>957
いちゃもん付けるな
それ位誰だってわかってるさ
エディタに全角空白は□が表示されるし

しかも質問者は<<が見つからないというエラーが
出ると言っているわけで、全角空白のエラーが
出ると言っているわけではないし
960デフォルトの名無しさん:2008/09/20(土) 14:21:20
うるせーよ
961デフォルトの名無しさん:2008/09/20(土) 14:22:05
頭悪そうな奴が一、二名いるな
962デフォルトの名無しさん:2008/09/20(土) 14:30:35
>>960
敗走ワロタ
963デフォルトの名無しさん:2008/09/20(土) 14:58:33
>>954
BCC6.1.0ではコンパイラエラーになるな
これはBCCのバグだろう
964デフォルトの名無しさん:2008/09/23(火) 00:38:22
template クラスの前方宣言はどのように記述すればいいのでしょう?
たとえば、

template< class T > hoge{ };

を前方宣言する場合です。
965デフォルトの名無しさん:2008/09/23(火) 00:42:20
template< class T > hoge;
966デフォルトの名無しさん:2008/09/23(火) 00:43:31
両方 hoge の前の class を忘れてるけどね
967デフォルトの名無しさん:2008/09/23(火) 00:59:18
できますた! どもです。
968デフォルトの名無しさん:2008/09/23(火) 12:57:42
templare で値を指定出来る?
例えば、こんな感じ。

template<class TValue>
class CHoge
{
int m_value;
public:
CHoge() : m_value(TValue) {}
};
969デフォルトの名無しさん:2008/09/23(火) 13:05:25
template<int TValue>
970デフォルトの名無しさん:2008/09/23(火) 13:14:39
classってのは、そういう意味だったのね。ありがとう。
971デフォルトの名無しさん:2008/09/23(火) 13:16:05
classよりもtypenameの方が意味がはっきりする
でもclassの方がタイプ量が少ないせいか皆こちらを使うね
972デフォルトの名無しさん:2008/09/23(火) 13:23:12
つかtypenameの導入の方が後だからじゃね
973デフォルトの名無しさん:2008/09/23(火) 16:11:32
typenameは存在自体が恥ずかしい予約語だから必要ないときはあんまり使いたくない
974デフォルトの名無しさん:2008/09/23(火) 16:31:44
どう恥ずかしいんだ?
975デフォルトの名無しさん:2008/09/23(火) 18:02:03
BYTEからcharへ変換する方法ってどうやるんでしょうか?

BYTE *dst;
ConvertINetString( &mode, 51932, 932, buf1, &srcLen, dst, &dstLen);

上のdstをchar型に変換したいと思っています。
976デフォルトの名無しさん:2008/09/23(火) 18:09:59
char *converted = reinterpret_cast<char*>(dst);
977デフォルトの名無しさん:2008/09/23(火) 18:35:35
>>975 BYTE の(意味的な)定義がわからないと、なんとも。
978デフォルトの名無しさん:2008/09/23(火) 19:09:04
979デフォルトの名無しさん:2008/09/23(火) 19:56:07
>>974
C++は自力で型名を型名と判別できない言語だから必要な予約語であって
一人でパースすらできない欠陥言語であることの証明だから
980デフォルトの名無しさん:2008/09/23(火) 20:00:24
そんな理由でなんでclassならいいんだよw
981デフォルトの名無しさん:2008/09/23(火) 20:50:48
typename は解析を簡単にするために必要なんじゃないの?
982デフォルトの名無しさん:2008/09/23(火) 21:08:06
typenameの読み方(訓読み)が恥ずかしいんじゃなかろうか
983デフォルトの名無しさん:2008/09/23(火) 22:04:29
読み方って、ちぺなめ以外に何かあるのか?
984デフォルトの名無しさん:2008/09/23(火) 22:05:42
なんてことをいうんだ
今後typenameを見るたびに恥ずかしい読み方を思い出すようになってしまったらどうしてくれるw
985デフォルトの名無しさん:2008/09/23(火) 22:18:51
>>984
にやにやしてあげる
986デフォルトの名無しさん:2008/09/23(火) 23:19:12
>>253
ちょwwww
987デフォルトの名無しさん:2008/09/24(水) 01:38:09
何処への誤爆かさっさと自白するなら、処遇の善処を考えないでもないぞ?
988デフォルトの名無しさん:2008/09/24(水) 01:58:04
普通に浦島レスに見える
989デフォルトの名無しさん:2008/09/24(水) 01:59:05
な、(ry
990デフォルトの名無しさん:2008/09/24(水) 02:38:37
まあ>>253は、書いてはいけないコードだからな
991デフォルトの名無しさん:2008/09/24(水) 12:44:49
CloseHandleでエラーが出たらどうしてる?
ログに残すくらいしか対策ないよな。
992デフォルトの名無しさん:2008/09/24(水) 12:51:11
例外投げるとか
どっちにしろ対処方はないんじゃね?
993デフォルトの名無しさん:2008/09/24(水) 16:01:38
精々OutputDebugStringする程度か、無視だな。
994デフォルトの名無しさん:2008/09/24(水) 16:37:07
enum{
ONE=1,
TWO=2,
THREE=4,
FOUR=8
};

ってフラグ定数を宣言したい時いちいち=で設定しないでもenumと同じ使い心地の定数の宣言できないだろうか
勝手に2倍2倍にしてくれるenumみたいな
995デフォルトの名無しさん:2008/09/24(水) 16:39:11
enum{
dumm0,
ONE,
TWO,
dumm11,
THREE,
dumm101,
dumm110,
dumm111,
FOUR
};
996デフォルトの名無しさん:2008/09/24(水) 16:39:36
プリプロセッサメタプログラミングが必要だぜ。
997デフォルトの名無しさん:2008/09/24(水) 16:58:07 BE:1113850548-2BP(40)
むしろ参照するときにマクロなり何なりで 1 << n する。
998デフォルトの名無しさん:2008/09/24(水) 17:53:39
>>995お前の発想にはいつも勃起させられているよ。まぁ、こっちこいよ。
999デフォルトの名無しさん:2008/09/24(水) 19:13:16
 
1000デフォルトの名無しさん:2008/09/24(水) 19:14:05
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。