C++相談室 part59

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

現行スレ
http://pc11.2ch.net/test/read.cgi/tech/1190745673/
3デフォルトの名無しさん:2007/10/20(土) 16:56:41
■基本■
[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)に対応。
4デフォルトの名無しさん:2007/10/20(土) 16:57:48
5デフォルトの名無しさん:2007/10/20(土) 16:58:31
6デフォルトの名無しさん:2007/10/20(土) 17:25:01
STLつかうと一気に実行ファイルサイズが10倍に?!

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

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

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

#include <stdafx.h>
後死ね。

言葉が悪いな。それで教えているつもりか。
まぁヒントぐらいにはなったな。
うむごくろう。
7デフォルトの名無しさん:2007/10/20(土) 17:31:26
これは、削除依頼を出すべきなのか?
8デフォルトの名無しさん:2007/10/20(土) 17:32:43
だね
どう見てもスレ立て荒らしでしょ
9デフォルトの名無しさん:2007/10/20(土) 17:41:24
>>7-8
削除依頼出しとけよ
10デフォルトの名無しさん:2007/10/20(土) 18:27:10
janeの隠し機能1

1.まず半角入力に切り替える
2.Wキーを押しっぱなしにする
3.Wキを押しっぱなしにしながらsageのチェックするところをおもむろにクリック
11デフォルトの名無しさん:2007/10/20(土) 18:59:37
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
12デフォルトの名無しさん:2007/10/20(土) 19:08:33
>>STLでファイルが十倍に

きっと
vector<int>;
vector<char>;
vector<string>
とかコンテナクラスの乱立になっているんだろうなぁきっと…
コンパイラオプションは弄ってないでしょうなきっと…。
13デフォルトの名無しさん:2007/10/20(土) 20:41:29
iostreamをインクルードするとexeが太っちゃうです。
14ネタにマジレス:2007/10/22(月) 10:14:41
>>10
ショートカットが働いているだけっしょ。隠し機能でもなんでもないじゃん。
15デフォルトの名無しさん:2007/10/25(木) 18:05:45
なんで bool って 32ビットもあるの?
重いから bool :1 って定義してるけど、32ビットも保持する意味あるの?
16デフォルトの名無しさん:2007/10/25(木) 19:30:08
真実を伝えるのに
1ビットで足りるとでも?
17デフォルトの名無しさん:2007/10/25(木) 22:09:51
実装によりけり
18デフォルトの名無しさん:2007/10/26(金) 00:45:32
>>15 それ、パディングでしょ。
19デフォルトの名無しさん:2007/10/27(土) 16:43:09
32ビットの方が軽いじゃん
20デフォルトの名無しさん:2007/11/08(木) 23:03:05
age
21デフォルトの名無しさん:2007/11/08(木) 23:47:49
いいじゃん32bitくらい
22デフォルトの名無しさん:2007/11/09(金) 04:06:19
立てるならちゃんとテンプレ書き込めよ糞>>1
23デフォルトの名無しさん:2007/11/17(土) 22:55:41
vector<bool>はダメダメよ
24デフォルトの名無しさん:2007/11/19(月) 19:55:18
traitsとpolicyとconceptの違いをおしえてくださいですぅ〜
英語のサイトに詳しく書いてあるぽいのですが英語読めないorz
25デフォルトの名無しさん:2007/11/19(月) 23:40:47
traitsは英語の意味そのまま、特徴とか性質
具体的には型の特徴をメンバとして持つクラステンプレート

policyも英語の意味のまま、方針
具体的には型の機能の一部をテンプレート引数としてMix-Inできるように書かれた型

conceptは型の型、つまりメタ型
C++0xではHaskellのclassに近いものになる
2625:2007/11/19(月) 23:52:40
>具体的には型の特徴をメンバとして持つクラステンプレート
ああ、テンプレートである必要はないか
27デフォルトの名無しさん:2007/11/23(金) 21:01:22
クラスの概念がイマイチ分からん。
クラスA、B、Cがあって、
class A {
 ...
 C c;
};
class B {
 ...
 C c;
};
みたいな感じにした際、Aクラスを介してアクセスするcの色々と
Bからアクセスするcは同じもの? 違うもの?

自分でも言ってる意味がわからないのだが、これは
A用に使うCのオブジェクトが生成されて、
B用にもCのオブジェクトがみたいなものが生成されて
別物をアクセスしてるんじゃないかなって。
実際はどうなんでしょうか?
28デフォルトの名無しさん:2007/11/23(金) 21:08:24
A a1;
A a2;
このとき a1.c と a2.c は別インスタンスだよな、それはOK?
29デフォルトの名無しさん:2007/11/23(金) 21:08:36
実際そうだよ。
30デフォルトの名無しさん:2007/11/23(金) 22:26:26
>>27
>27のclassをstructに置き換えても理解できない?
31デフォルトの名無しさん:2007/11/23(金) 22:31:03
すんません、適当に加算するプログラムを作って理解できました
>>30の言うとおり、structみたいなのを考えると当たり前ですね。
失礼しました

あと、staticを付けた変数は共有できるんですね。 頑張ります
32デフォルトの名無しさん:2007/11/23(金) 22:31:05
>>27
クラスって型のことだよ。structと同じ。
あとその型で定義したオブジェクトだけに使える関数があって
これをメソッドという。
33デフォルトの名無しさん:2007/11/23(金) 22:35:51
バカヤロウ。 C++ スレではメンバ関数といえ。
34デフォルトの名無しさん:2007/11/23(金) 22:41:26
別にどっちでもいいっすよー。
35デフォルトの名無しさん:2007/11/23(金) 23:53:11
いつも、けいしょ・・・派生クラスって言い直してしまう(´・ω・`)
36デフォルトの名無しさん:2007/11/23(金) 23:59:02
>>35
わかるw 俺の場合メンバ関数も、メソ・・・メンバ関数と言い直してしまう。
37デフォルトの名無しさん:2007/11/24(土) 00:01:18
マサルさんネタかよっ
38デフォルトの名無しさん:2007/11/24(土) 10:14:16
大きくABCと3つの処理に分かれていて、テンプレートを使ってBの部分だけ処理内容を自由に変えたいと思ったのですがうまくいきません。

A
B1 <--> B2 <--> B3 etc.
C

Bの部分の関数呼び出しの引数が固定ならなんとかなるのですが、
テンプレートパラメータとして可変長引数を扱うにはどうすればいいと思いますか?
誰か教えてください
39デフォルトの名無しさん:2007/11/24(土) 11:01:01
想定する引数の数だけテンプレート用意したらいいんじゃね?
それか、引数を構造体にまとめて1つとして扱うとか。
4038:2007/11/24(土) 14:13:13
他人に(好き勝手に)使ってもらうように作るので無理です
なるべく自由につかってもらいたい
41デフォルトの名無しさん:2007/11/24(土) 14:23:01
>>38
なんで固定の A, C の間に挟む処理の引数が可変長になるんだ?
無理にテンプレート使おうとしてうまくいってないだけじゃね?
42デフォルトの名無しさん:2007/11/24(土) 14:30:09
つか>>38が本当に必要になのか
43デフォルトの名無しさん:2007/11/24(土) 14:39:10
可変長パラメータやデフォルト値を使うのじゃダメなのか
44デフォルトの名無しさん:2007/11/24(土) 16:16:00
Bの部分をファンクタにして渡せばいいだけだろ。
ファンクタはメンバも持てるんだから追加の引数はそこに入れて渡せ。
4538:2007/11/25(日) 14:52:25
やっぱり無理かなあ
AとCは自分で作るからいいとして
Bには制限をつけたくないんです

基本的にBを使うのは何もわかってないアホだと思ってください
46デフォルトの名無しさん:2007/11/25(日) 14:56:48
だれも無理だなんて言ってないのに、なんでそうなる?
47デフォルトの名無しさん:2007/11/25(日) 15:03:18
38のレベルの誰でもが使えるように、というのならば、無理かもしれない。
48デフォルトの名無しさん:2007/11/25(日) 15:04:17
何もわかってないアホが C++ 使う時点でかなり無理があるからな。
49デフォルトの名無しさん:2007/11/25(日) 15:10:01
Java使わすほうが適当だな。
50デフォルトの名無しさん:2007/11/25(日) 15:27:51
本質的な解決になっていない気もするけど。
51デフォルトの名無しさん:2007/11/25(日) 15:48:54
アホが使うなら制限付けるだろ、常考。
52デフォルトの名無しさん:2007/11/25(日) 17:15:31
44で答え出てるじゃん。
5338:2007/11/25(日) 20:15:13
みんなまじめに考えようよ
難しいとは思うけどさ…
54デフォルトの名無しさん:2007/11/25(日) 20:22:31
部品をやるよ。
boost::any
std::vector
5538:2007/11/25(日) 20:29:57
>>54
いいから考えてください。
56デフォルトの名無しさん:2007/11/25(日) 20:32:55
答えはもう出てる。
5738:2007/11/25(日) 20:33:39
↑キミ偽者

理想はラムダ関数なんですけどね。
58デフォルトの名無しさん:2007/11/25(日) 20:34:53
ずばり答え言ってやれよ
いくつかある異なるゴールへのヒントばかりでかわいそうになってきた
59デフォルトの名無しさん:2007/11/25(日) 20:39:10
それにはエスパーが必要だ。情報が足りなさすぎる。
60デフォルトの名無しさん:2007/11/25(日) 20:40:29
情報足りなくて答えられないのにえらそうにしてたのかw
61デフォルトの名無しさん:2007/11/25(日) 20:41:27
情報が足りないのが回答者のせいだとでも思ってるのか?
62デフォルトの名無しさん:2007/11/25(日) 20:43:45
もうやめろよ 38
6338:2007/11/25(日) 20:45:33
俺のせいではないな
問題はA、B、Cと3つの処理があってBを自由に取り替えたいだけだからな

A
B1 <--> B2 <--> B3
C

みたいな感じだな
64デフォルトの名無しさん:2007/11/25(日) 20:47:03
情報が足りないもなにも、>>44でええやん
6538:2007/11/25(日) 20:53:09
関数オブジェクトは駄目
わかんない人いるから
66デフォルトの名無しさん:2007/11/25(日) 20:54:08
>>38
ここで答えを待ってる間に>>38はさっさと自分で作ればいいんじゃね?
6738:2007/11/25(日) 20:58:33
本当にここは役に立たないインターネッツですね
6838:2007/11/25(日) 21:00:25
↑キミ偽者
自分で作れないから聞いてるんですが…
6938:2007/11/25(日) 21:00:45
ちょっと鍛えてあげようと思って
お題を投下してやったらこれだ

意欲も才能もないのになんで
プログラムやろうと思ったの、きみら?
70デフォルトの名無しさん:2007/11/25(日) 21:10:36
38 大杉
7138:2007/11/25(日) 21:18:27
キミも偽者

いやほんとマジでお手上げなんですが…
72デフォルトの名無しさん:2007/11/25(日) 21:22:37
だから何?
ってか、A, CだけじゃなくてBも【全部】自分で作ればアホに提供できるだろが。
7338:2007/11/25(日) 21:30:55
ライブラリ屋なんで上のレイヤーまで面倒みれないです
74デフォルトの名無しさん:2007/11/25(日) 21:38:43
>>73
どんなライブラリを提供したいのか、もそっと具体的に書ける? ロギング?
75デフォルトの名無しさん:2007/11/25(日) 21:39:09
Bはコールバックなの???
だったら関数仕様を明確にするだけでいいんじゃね?
76デフォルトの名無しさん:2007/11/25(日) 21:47:21
ABCをメソッドに持ったクラスXを作って、
Bに渡す引数は全部Xのメンバ変数にしておけ。
そうすりゃBに引数はいらない。
77デフォルトの名無しさん:2007/11/25(日) 21:49:53
ファンクタはだめなのに、ラムダ関数ならいいのか。ウンコ
78デフォルトの名無しさん:2007/11/25(日) 21:50:07
In function `main':
/main.cxx:23: undefined reference to `Environment(double, double, std::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
collect2: ld はステータス 1 で終了しました

というエラーがg++で出ました。
-lmはつけてるし仮想関数でもないし、ちょっと意味がわかりません。
どこを考えればいいのか思いつく方いらっしゃいませんか?
79デフォルトの名無しさん:2007/11/25(日) 21:52:16
Environmentへ渡してる引数の型が間違ってんじゃねーの?
80デフォルトの名無しさん:2007/11/25(日) 21:55:01
>>65
でもさ、理想はラムダ関数って>>57でいっているよね。
関数オブジェクトを受け取るようにしておけば、
Boost.LambdaやC++0xで導入されるかもしれないラムダ関数なども受け付けられる。
関数オブジェクトがわからなければとりあえず普通の関数を作って渡せばいい。

こんな関数オブジェクトのどこに問題がある?
81デフォルトの名無しさん:2007/11/25(日) 21:59:46
>79
ありがとうございます!
引数を確認するときにdoubleかstringかーしか見てませんでした。
宣言のところ(自作ヘッダーファイルの中)と定義のところで
参照の&がついてるかついてないかという違いを見落としていました。
くだらんミスでごめんなさい。ありがとう!
8238:2007/11/25(日) 22:10:03
世の中の人間が全員関数オブジェクトを理解できると思っては駄目です。
アホなんです。基本的に。

今のC++の仕様では不可能ということで結論も出たのでもう寝ます。
ありがとうございました
83デフォルトの名無しさん:2007/11/25(日) 22:13:21
>>82
そういうときはこう答えないと相手にしてもらえないよ

> 言葉が悪いな。それで教えているつもりか。
> まぁヒントぐらいにはなったな。
> うむごくろう。
8480:2007/11/25(日) 22:18:30
>>82
誰も、というより少なくとも俺は全員理解できるなんて言っていないぞ。

なんなら関数へのポインタを引数に取るものを多重定義しておくか。
そうしたら今度は世の中全員が関数へのポインタを理解できると思うな
とでも言ってくるんだろうな。
85デフォルトの名無しさん:2007/11/25(日) 22:20:16
正直そんなレベルの職場で一人だけ張り切って柔軟性がどうだとか滑稽だと思う
86デフォルトの名無しさん:2007/11/25(日) 22:25:15
結局どういうものを要求してたのかよくわからない
87デフォルトの名無しさん:2007/11/25(日) 22:35:07
>>85
同意。
もちろんチームのスキルの底上げをやり遂げられる人もいるが、
>>38にはそのつもりもないようだし、それなら程度に合わせてコードを書くべきだ。
88デフォルトの名無しさん:2007/11/25(日) 23:07:51
すいません。
2次元配列 d[3][3] に対するポインター (*p)[3] を作って
p=d
とやったのにcannot convertとかエラー出たんですがわかりませんか?
89デフォルトの名無しさん:2007/11/25(日) 23:10:39
>>88
2次元配列だろうが何次元だろうが、関係ない。
int d[3][3];
int *p;
p = d;
90デフォルトの名無しさん:2007/11/25(日) 23:12:36
>>89
ちょwwそれコンパイルエラー
9188:2007/11/25(日) 23:14:21
エラー詳細は
error: cannot convert `int[((unsigned int)((int)ObjNum))][((unsigned int)((int)DataNum))]' to `unsigned int (*)[6]' in assignment
です
どういうことでしょうか?
9238:2007/11/25(日) 23:18:35
自己解決しました
93デフォルトの名無しさん:2007/11/25(日) 23:20:19
>>91
そのエラーを吐くソースはってみ?
94デフォルトの名無しさん:2007/11/25(日) 23:21:17
2次元配列に対するポインタは
(*)[][]
でしょうに。
でもって
p=&d;
だろうに。
95デフォルトの名無しさん:2007/11/25(日) 23:25:25
p = &d[0][0];
で代入すりゃいいんじゃねーの?
9688:2007/11/25(日) 23:29:38
void Entry(void)
{
   (省略)
int d[ObjNum][DataNum];// ちなみに4と6です
                   //[]の2つはグローバルなint変数です
(省略)

     for(int i=0;i<ObjNum;i++){
fp >> n[i];
for(int k=0;k<DataNum;k++){
fp >> d[i][k];
}
}

data=d;

}

ソースを分割してて main関数のあるところでグローバルとして以下を宣言
int (*data)[6];

でエラります。(91の書き込みのときのunsignedは気にしないでください)
アドバイスしていただいたものイチから試してみます!
ありがとうございます!
9788:2007/11/25(日) 23:43:51
どれも駄目でしたorz
98デフォルトの名無しさん:2007/11/25(日) 23:44:45
>>96
double (*p)[DataNum];
こんな感じで。
99デフォルトの名無しさん:2007/11/25(日) 23:45:43
dataに代入する目的は?
100デフォルトの名無しさん:2007/11/25(日) 23:45:57
doubleじゃなくてintだった
int (*data)[DataNum];
10188:2007/11/25(日) 23:59:31
>99
そういえばコレ外部で使おうとするときには
ポインター先消えますね汗
2重に馬鹿でした。
ポインターに代入したのはファイルからロードしたデータをプログラム内
どこからでも参照できるようにしたかったからです。
じゃあ配列自身をグローバル化しろよって話ですね。。。
>100
そのとおり書いてあるはずなんですが・・
10288:2007/11/26(月) 00:08:26
配列をグローバル化しようとすると要素数を決めておかないといけないので
それが嫌で中で宣言したんです。
ポインターを作るときにも要素数が必要だってのがわかったので今となっては
意味のない代入かもしれませんが出来ないってとこがどうしても納得できません。
103デフォルトの名無しさん:2007/11/26(月) 00:11:35
C++なんだから、STLおぼえたほうがいいよ。
std::vectorで動的配列作れる。
104デフォルトの名無しさん:2007/11/26(月) 00:12:47
>>102
>int d[ObjNum][DataNum];// ちなみに4と6です
このDataNumは定数じゃなくて動的な値? これってCの新しい規格の奴だよね。
使ったことないから詳しくは知らないが、型のサイズが動的に決まる、
つまりコンパイル時に特定できないのなら、そこから int(*)[6] へのキャストは無理でしょ。
10588:2007/11/26(月) 03:24:33
みなさまアドバイスありがとうとざいましたm(__)m
うんうん唸って結局以下の様にしました。

main関数のあるソースファイルで
vector<vector<double> > *data;

Entry関数のあるソースファイルで。
vector<vector<double> > d(ObjNum, vector<double>(DataNum));
および
data=*d;

別の関数でdataを使うとき
ac = (*data)[x][y];

配列の大きさを自動判別にしたかったためこのようになりました。
103、104、およびhttp://gimite.net/bcbqtree/qtreemain.cgi?mode=thread&thread=424
とても参考になりました。
みなさまほんとにありがとうございました!
106デフォルトの名無しさん:2007/11/26(月) 11:18:45
int *p = NULL;
...
delete p;

ってコードみたんだけど、pがNULLかどうかチェックしてなくてdeleteしてるの。
これってNULLをdeleteしてもOKみたいなこと規格にあるの?
規格厨ヘルプ!
107デフォルトの名無しさん:2007/11/26(月) 11:25:53
deleteの対象がぬるぽである場合、何もしない(ISO/IEC 14882:2003 5.3.5.2)
なんで問題ないでしょう
108デフォルトの名無しさん:2007/11/26(月) 19:01:58
なにーサンクスです。
じゃぁ結局ifでチェックするコードは無駄なんですね
109デフォルトの名無しさん:2007/11/26(月) 20:58:26
Releaseと紛らわしいからどっちもifつけてる俺は異端か
110デフォルトの名無しさん:2007/11/26(月) 21:03:40
>>109
・効率が悪い
・知らないと思われるのが腹立たしい

よって、つけないのが良いと思います。
111デフォルトの名無しさん:2007/11/26(月) 21:06:38
古いコンパイラだと NULL 渡すと落ちたことあったような気がする。
112デフォルトの名無しさん:2007/11/26(月) 21:11:51
規格が出来る前のやつだとそういうのもあるかもしれませんね
113デフォルトの名無しさん:2007/11/26(月) 21:20:15
最適化で消えるなら、古いコンパイラを考慮して if つけてもいいとは思う。
114デフォルトの名無しさん:2007/11/26(月) 21:33:20
NULLじゃなくて0じゃね? ほとんどの場合int(0)だとは思うけどさ。
115デフォルトの名無しさん:2007/11/26(月) 21:51:17
無理に難しい事言おうとして変な事言ってるな。
116デフォルトの名無しさん:2007/11/26(月) 22:14:40
NULLは(void*)0か(int)0しか見たことないな。
117デフォルトの名無しさん:2007/11/26(月) 22:20:07
Cの規格ではヌルポインタ定数(NULL)は整数定数0かそれをvoid*に変換したもの
と言われてるからなあ
C++ではヌルポインタ定数は0だからNULLマクロを使うなら(int)0と
すべきか????
118デフォルトの名無しさん:2007/11/26(月) 22:24:27
今は NULL は処理系定義だよ。
__null 拡張キーワードで定義されてたりする。
119デフォルトの名無しさん:2007/11/26(月) 22:30:59
>>118
Cのヌルポインタ定数の定義が規格でも変わったの?
俺が見たのはJIS X 3010 (2003年)だけど。
C++はプログラミング言語C++しか見てないから
わからない。
120デフォルトの名無しさん:2007/11/26(月) 22:32:50
C は C99 で変わった。
C++ はいつからなのかは知らん。
121デフォルトの名無しさん:2007/11/26(月) 22:34:01
>>120
thx
知らんかった。
122デフォルトの名無しさん:2007/11/26(月) 22:38:02
とりあえず g++ だとこれで __null と出力される。
VC++ はどうなのかな?

#include <iostream>

#define BARE_2(macro) #macro
#define BARE_1(macro) BARE_2(macro)
#define BARE(macro) BARE_1(macro)

int main() {
std::cout << BARE(NULL) << std::endl;
}
123デフォルトの名無しさん:2007/11/26(月) 22:38:07
VC++6.0ってコンパイルしてexeやDllが作成された時点でANSI規格に準拠しるって言えるのでしょうか?
知っている人います?
124デフォルトの名無しさん:2007/11/26(月) 22:39:02
VC6はC++98より前なんで割と準拠度低い
125デフォルトの名無しさん:2007/11/26(月) 22:41:02
言語拡張を使用しない という感じのオプションを付けてコンパイルすれば
まあ C なら C89 にはおおむね準拠できてると思うけど、100% じゃないんじゃないかな。
C++ に関しては VC++ 6.0 は C++ の規格が固まる前に出たというものもあってか、
C++ の規格への準拠率は酷いもん。
126デフォルトの名無しさん:2007/11/26(月) 22:42:21
そうなんですか。。。
ANSI準拠かどうかの判断をしたいのですが、何かいい手段(方法)ありませんか?
コンパイルオプションZaを指定するとコンパイルエラーが出ちゃうし。
ANSI準拠が今回の案件の用件の一つに入っているのでなにかいい案ないでしょうか。
127デフォルトの名無しさん:2007/11/26(月) 22:44:29
C なら lint があるけど、C++ ではあったっけ?
128デフォルトの名無しさん:2007/11/26(月) 22:48:14
>>126 g++ -ansi -pedantic -fsyntax-only -Wall -Wextra
129デフォルトの名無しさん:2007/11/26(月) 22:53:14
ってか、ビルドされたものに対してANSI準拠とかあんの?
コードなら他のコンパイラでも(ANSI準拠なら)問題ないんだから>>128みたいなかんじでいいんでね?
130デフォルトの名無しさん:2007/11/26(月) 22:59:13
C は ANSI → ISO/IEC の順だから ANSI でいいけど
C++ は ISO/IEC → ANSI の順だから ISO って言った方がいい気がする。
まあどうでもいい話だが。
131デフォルトの名無しさん:2007/11/26(月) 23:05:02
JISもあるよ☆
132デフォルトの名無しさん:2007/11/27(火) 00:18:02
void ○○○::□□□(int a){

}

ってこれなんですか?C++の自作関数ですか?
この関数が他に使われてるところを調べるにはどうしたらいいんでしょう?
133デフォルトの名無しさん:2007/11/27(火) 00:29:07
名前空間内の関数か、クラスのメンバ関数の定義。
どこで使われているかを探すには、Cと大差ない。
IDEの機能に頼ったり、grepしたり。Cより見付けにくいかもしれないけど。
134デフォルトの名無しさん:2007/11/27(火) 00:39:23
>>133
ありがとうございます!恩にきます!
ですが、すみません。Cもあまりよくわかってないのですが、
○○○::□□□
だけでgrepしたところ、一件もヒットがないのです。
○○○だけで検索すべきでしょうか?□□□の方が真髄なのでしょうか?
135デフォルトの名無しさん:2007/11/27(火) 00:45:55
>134
□□□の方が関数の名前なのでそっちで検索する…んだけど、○○○::□□□じゃない□□□も
引っかかる可能性があるんで、それ以上は C++ 勉強してくれって感じ。
136デフォルトの名無しさん:2007/11/27(火) 00:49:11
□□□で検索すべきだろう。
類似する関数があれば○○○がクラスなら継承の有無を確認する必要がある。
137デフォルトの名無しさん:2007/11/27(火) 00:53:49
>>135
大変助かります。ありがとうございます。
□□□がメンバ関数にあたるのでしょうか?
すみませんが、もう一つだけ!
○○○::~□□□()
となってるのがありますが、これはちょっと何か特殊なのでしょうか?
138デフォルトの名無しさん:2007/11/27(火) 00:55:42
>>137
入門の本なりサイトなりを参考にするといいよ。
○○○::~□□□←これはデストラクタ。
この程度の内容なら猫でもなんでもいいから一読すりゃ覚えられる。
139デフォルトの名無しさん:2007/11/27(火) 01:08:26
>>136
クラスやら継承やらを学べばいいですね!ありがとうざいます!
>>138
猫って、、、これですか?
http://www.kumei.ne.jp/c_lang/
一読すりゃ覚えられるかどうかはアレですが・・易しく書いてありそうですし
猫好きなのでなんとかなりそうです。挑戦してみます!
(一括ダウンロードとかあれば携帯に入れられるのに!)
140デフォルトの名無しさん:2007/11/27(火) 01:16:09
また不毛なNULLに関する論争か。
禿と、ハーブ・サッターたんが提案したこれとか、ここの住人的にはどうよ?
ttp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf
141デフォルトの名無しさん:2007/11/27(火) 01:27:02
今更感がある。恩恵も少なそうだし。
142デフォルトの名無しさん:2007/11/27(火) 01:31:52
>>139
あ、有名だから出したってだけでそこにあるコードがいい物じゃないんで、一応。
大体の基礎的なことが猫の20章までにあるからそこまで読めば十分。
C++で使われる単語(コンストラクタとかデストラクタ、継承、オーバーロード等)が
多少理解できるようになればいろんなサイト回ったほうがいい。
143デフォルトの名無しさん:2007/11/27(火) 01:39:38
>>142
ひとまずは目の前にある大量のソースを読めるようになり、簡単な修正が
できるようになることが目標ですので、基礎が身につけばいいです!
コンストラクタとかデストラクタ、継承、オーバーロードなどが目安ですね!
Cを一通りやったはずなのに、目の前のコードの意味が分からず、C++だったことに
気付き、涙目になってたところでしたので、本当に大っ変、大っっ変助かりました!!!
展望が見えてきました!!!ひとまずやってみます。ありがとうございました!!!
144デフォルトの名無しさん:2007/11/27(火) 01:58:57
>>141
やっぱりそう思う?
でもここでも毎度毎度でてくるじゃん。
もう何度この手のやり取りを見たことか。

おい、NULLとは何だ規格厨ども?
マクロに決まってんだろボケ!
値は0か? それとも((void *)(0))か?
いや、それは処理系依存だ。
規格でも0だと決まっているぞアホが。
いや、しかしだな、実際昔のある処理系では云々。


何かしら必要とされているんじゃない?
145デフォルトの名無しさん:2007/11/27(火) 02:01:42
>>144
必要なものっていうなら、ずっと昔からある C FAQ 5 で十分。

どうせ互換性は捨てられないんだから 0 も NULL も残る。そこにさらに nullptr を
追加しても、混乱は増すだろう。一部の問題を解決するのは確かなんだけれども。
146デフォルトの名無しさん:2007/11/27(火) 02:06:08
すいません。ある返り値の組(1,2,3)があって
例えば
1 2/3
2 1/6
3 1/6
の確率で返すことが決まっているときにどのように書けば
この確率どおりに返り値を返すことができるでしょうか?
147デフォルトの名無しさん:2007/11/27(火) 02:15:33
C++では今の0でいいじゃん。コンパイラ作る奴らしっかりしろ。
148デフォルトの名無しさん:2007/11/27(火) 02:18:29
>>146
int foo() {
 switch (rand() % 6) {
 case 0:
  return 2;
 case 1:
  return 3;
 default:
  return 1;
 }
}
149デフォルトの名無しさん:2007/11/27(火) 02:18:44
>>146
乱数使えって授業で言ってなかった?
150デフォルトの名無しさん:2007/11/27(火) 02:19:20
ここでアセンブラの事聞いてもよろしいでしょうか?
ここしか人いなさそうなので…
151デフォルトの名無しさん:2007/11/27(火) 02:21:11
rand()は実用で使おうとすると問題あるんじゃなかったかな
例えばサイコロを再現しようとしても、均等に値が分かれないとか…
なんか実用的な乱数ライブラリあった気がするけど、思い出せない
152デフォルトの名無しさん:2007/11/27(火) 02:27:07
有名な乱数ライブラリならメルセンヌ。暗号には使えないようだけど。
プログラムサイコロの再現なんて、ほんとにできたらノーベル賞もんだけどな。

>>150
アセンブラすれあるし、言語関係ないスレでもいいんでね?
http://pc11.2ch.net/test/read.cgi/tech/1187079488/
153デフォルトの名無しさん:2007/11/27(火) 02:31:06
>>152
ありがとうございます
一応アセンブラスレには書き込んだんですけど
こっちでも聞いてみてもいいでしょうか?
154デフォルトの名無しさん:2007/11/27(火) 02:31:09
とりあえずrandomとかrand_sでお茶を濁す。
155デフォルトの名無しさん:2007/11/27(火) 02:33:12
>>151
srandとtime関数使って種別変えてもダメなの?
156デフォルトの名無しさん:2007/11/27(火) 02:38:05
>>152
>プログラムサイコロの再現なんて、ほんとにできたらノーベル賞もんだけどな。
知らなかった

>>155
関係ないはず
本物のサイコロ使うと 6 が連続して出るなんてことも結構な頻度で起こるけど
コンピュータの乱数だと、そんな風にならない…という話だったような
157146:2007/11/27(火) 02:38:08
>>148,149,154
ありがとうございます。
分母を最小公倍数で消して
1 4
2 1
3 1
とした上でrandom関数にmax6min0で返り値吐かせて
0〜4なら1を、4〜5なら2を、・・という風にしようかと思います。
返り値の組は変動するのでswitchには乗せられないと思ったので。。
158デフォルトの名無しさん:2007/11/27(火) 07:12:58
>>156
サイコロのかわりに (rand() % 6) + 1 なんてしてると、そんなことになりやすいかもね。
C FAQ にある方法使えば、値域が十分小さいときにあんまりひどい結果にはならないと思うよ。
159デフォルトの名無しさん:2007/11/27(火) 10:41:50
STLのmapを2重に使う場合インサートはどうやってやればいいんでしょうか
map<string, map<int,int> > a;
こんな感じでKeyをstringとintにしたいんです・
使うときa["test"][100]++;という具合にカウントしていきたいんですが
160デフォルトの名無しさん:2007/11/27(火) 10:57:04
普通にinsertできるが、コンテナの中にコンテナはどうかと……
Keyをstringとintの構造体かクラスにして、Compare指定したらどうだろ
161159:2007/11/27(火) 11:10:04
>>160
ありがとうございます。
では自分で自作する方針で行きたいと思うのですが
Compare指定について勉強するサイトを教えていただけませんか・・
(浅いものでコンペア指定という語を初めて聞きました)
162デフォルトの名無しさん:2007/11/27(火) 11:41:24
サイトが見当たらなかったので、使用してるSTLのソースを参考にしてみると良いかも

こんな感じに:
template <class T> struct less_key2 {
bool operator()(const T& s1,const T& s2) const { return s1.first < s2.first && s1.second < s2.second; }
};
typedef std::pair<std::string,int> Key2;
std::map<Key2,int,less_key2<Key2> > a;
163159:2007/11/27(火) 12:17:04
返事遅くなりました!
すみません、わざわざソース探していただいて。
参考にしつつ考えてみます!ありがとうございましたm(__)m
164鈴木:2007/11/27(火) 13:12:56
MiniDumpWriteDump をつかって、Dumpを出力しているのですが、
どのようにしてファイルの中身は見れるでしょうか?
165デフォルトの名無しさん:2007/11/27(火) 14:08:36
>>164
仕様にそんな名前のものはありません。環境依存スレにでもどうぞ。
166鈴木:2007/11/27(火) 14:56:16
>>165
仕様って何ですか?
C++って1つじゃないんですか?
167デフォルトの名無しさん:2007/11/27(火) 15:02:55
>>166
C++ に MiniDumpWriteDump などというものはありません
Windows API の話は↓へ

Win32API質問箱 Build59
http://pc11.2ch.net/test/read.cgi/tech/1194701996/
168デフォルトの名無しさん:2007/11/27(火) 15:03:42
MiniDumpWriteDumpはWindowsのAPIであって、
C++言語の話ではないってこと
169デフォルトの名無しさん:2007/11/27(火) 15:03:52
>>166
寧ろ、初心者スレへどうぞ。
170デフォルトの名無しさん:2007/11/27(火) 15:05:08
>>165
こういうレスする奴って性格悪そうだな
普通に誘導すりゃいいじゃん
171デフォルトの名無しさん:2007/11/27(火) 15:06:34
このスレに人がたくさん居ることに驚いたぜ
172165:2007/11/27(火) 15:12:25
>>170
私の性格を云々したいのなら、雑談スレへどうぞ。
どうせそちらもチェックしていますから。
173デフォルトの名無しさん:2007/11/27(火) 15:37:44
>>170
鼻から悪魔を召喚したいのですがどのスレが適切でしょうか?
174デフォルトの名無しさん:2007/11/27(火) 15:40:57
規格書を読んでundefinedって書いてあることを片っ端から試していくと良いです
175デフォルトの名無しさん:2007/11/27(火) 16:03:55
>>165

>>167>>168
176鈴木:2007/11/27(火) 20:40:23
>>167
ありがとうございます

逝って来ます
177デフォルトの名無しさん:2007/11/28(水) 01:03:23
>>162
なんか初心者スレに似たような比較関数で嵌ってる奴いたな。同一人物か?
ちゃんと Strict Weak Ordering にしないとダメでしょ。
178デフォルトの名無しさん:2007/11/28(水) 09:54:12
>>177
Strict Weak Ordering ですが、>>162の例で言うと
どういう規則になるんですか?

s1.first < s2.first && s1.second < s2.second

これがStrict Weak Orderingを満たしているということは
どういう意味?こういうのは直感的に分かるもの?
179デフォルトの名無しさん:2007/11/28(水) 10:01:11
s1.first < s2.first && s1.second < s2.second

なんかこれ違う気がする。。
s1.firstとs2.firstが一致した場合、secondを調べないで
falseを返すことになるけどいいのかな?条件が複数あると
混乱してくる。
180デフォルトの名無しさん:2007/11/28(水) 10:26:48
if (s1.first != s2.first) return s1.first < s2.first;
return s1.second < s2.second

が正しい。

というか、 std::pair<T, U> は標準で比較演算子持ってるから
基本的に自分で書かなくてよい。
181デフォルトの名無しさん:2007/11/28(水) 10:49:55
>>180
なるほど。

例えばboostのtuple使った場合、Strict Weak Ordering は

if( t1.get<0>() != t2.get<0>() ) return t1.get<0>() < t2.get<0>();
else if( t1.get<1>() != t2.get<1>() ) return t1.get<1>() < t2.get<1>();
else if( t1.get<2>() != t2.get<2>() ) return t1.get<2>() < t2.get<2>();

・以下続く

となるんですか?
182デフォルトの名無しさん:2007/11/28(水) 11:00:13
>>181
汎用的なコードにするためには、 operator != が定義されていない場合も考慮して
↓のようにしたほうがいい。これなら operator < しか使わない。

if( t1.get<0>() < t2.get<0>() ) return true; else if( t2.get<0>() < t1.get<0>() ) return true;
if( t1.get<1>() < t2.get<1>() ) return true; else if( t2.get<1>() < t1.get<1>() ) return true;
if( t1.get<2>() < t2.get<2>() ) return true; else if( t2.get<2>() < t1.get<2>() ) return true;

・以下続く

return false;

ポインタが入ってることを考えると厳密には std::less を使わないといけないんだけど、
激しくメンドイ。
183182:2007/11/28(水) 11:00:55
ミスった。行末の return true は return false の間違い。
184デフォルトの名無しさん:2007/11/28(水) 11:01:59
>>181
辞書式比較を実装するならそう。
(ただし、型によっては != 演算子を実装してないかもしれないので
 そこは回避する必要があるかも)

ただ、 strict weak ordering を満たす順序づけは一通りではないので、
別のやり方で順序を定義してもいい。
一般には、以下の条件が満たされる比較順序なら何でもいい。
  ある型の値 x, y, z に対して
    1. x < x は false
    2. x < y が true ならば y < x は false
    3. x < y と y < z が両方 true ならば x < z も true
    4. x < y, y < x, y < z, z < y が全て false ならば x < z と z < x も false
185デフォルトの名無しさん:2007/11/28(水) 11:18:29
4つ目の条件の意味がよくわからない
186デフォルトの名無しさん:2007/11/28(水) 11:23:00
>>185
書き換えれば、x == y, y == z が言える状況なら、 x== z も言えないといけないということ。
x < y, y < x がどちらもfalseなら1.から当然、x == y と言えるから。
187デフォルトの名無しさん:2007/11/28(水) 11:24:07
x < y かつ y < x ってのは x と y が等価(equivalent)であるということ。
このことを x≡y と書くとすると、4番目の条件は
    x≡y かつ y≡z ならば x≡z
と書き換えられる。

要するに、等しい連中同士を比べたら必ず等しくなってないと駄目だってこと。
188デフォルトの名無しさん:2007/11/28(水) 11:32:40
>x < y かつ y < x ってのは x と y が等価(equivalent)であるということ。
惜しい。この説明だとおかしい。
189デフォルトの名無しさん:2007/11/28(水) 11:44:25
>>182
!= は < で表現できるから、!= が定義されていない場合がある
ということですよね?

この例の場合>>184の1の条件と2の条件を使ってるということですね。
確かEffectiveSTLにStrict Weak Oderingの一つとして比較対象が一致
した場合は常にfalseを返すことが必要と書かれていました。これは、
>>184の1の条件ということですね。

奥が深いです。

みなさん、どのような書籍を読まれてるのですか?
190デフォルトの名無しさん:2007/11/28(水) 11:47:02
>>188
!(x < y) かつ !(y < x) が true かつ true ならば
つまり『一方が他方の前にあるということはない』
と解釈しました。
191デフォルトの名無しさん:2007/11/28(水) 11:47:27
>>177
それ書いたの俺だ、しかも比較文を間違えてるね
>>159さん、巻き込んだみんなもごめん

演算子はoperator<とoperator==は実装されていると思うけど、
他の人が言うとおり、operator==(!=)は極力避ける方向で>>162の比較は下になります

if (s1.first < s2.first) {
 return true;
} else {
 if (!(s2.first < s1.first)) {
  return s1.second < s2.second;
 } else {
  return false;
 }
}
192デフォルトの名無しさん:2007/11/28(水) 11:55:19
x != y を < で表現した場合、

!(x < y) && !(y < x)

ということで正しいですか?
193191:2007/11/28(水) 12:04:06
分かりにくそうなので修正です。

if (s1.first < s2.first) {
 return true;
} else {
 if (!(s2.first < s1.first)) {//if (s1.first <= s2.first) {
  return s1.second < s2.second;
 } else {
  return false;
 }
}

>>192
!(x < y) && !(y < x)
(x >= y) && (y >= x)
(x > y) || (x == y) && (y > x) || (x == y)
(x > y) && (y > x) || (x == y)
(x == y)
194デフォルトの名無しさん:2007/11/28(水) 12:06:29
(x > y) || (x == y) && (y > x) || (x == y)   …×
((x > y) || (x == y)) && ((y > x) || (x == y)) …○
195デフォルトの名無しさん:2007/11/28(水) 12:06:46
>>193
>(x > y) || (x == y) && (y > x) || (x == y)
間違い。
196デフォルトの名無しさん:2007/11/28(水) 12:48:14
assert マクロって必ず assert (x) を !!x で評価してくれるのかな。
ってのは、クラスに ! 演算子をオーバーロードしておけば
そのインスタンスを assert () に渡せるかなと思って。
一応 VC8 見たら !!x で評価してたけど、処理系依存?

クラスの内部状態が整合性ある状態かどうかを自己診断して
失敗なら true、成功なら false 返す処理を ! 演算子で
やろうと思ってます。

えと、なんか気持ち悪いけど失敗なら「true」でいいんだよね・・
197デフォルトの名無しさん:2007/11/28(水) 12:51:27
operator ! よりも operator bool のがいいんじゃないかと思う
198デフォルトの名無しさん:2007/11/28(水) 13:09:57
使うならsafe bool idiom使おうね…
199196:2007/11/28(水) 15:38:24
ios_base でも

bool operator!() const{
  // test if no stream operation has failed
  return (fail());
}

ってやってるし、「ダメ」なときに真を返せばいいのかなぁ。
200196:2007/11/28(水) 15:39:41
>>197-198
リロードせずに書いてしまった・・・
safe bool idiom ってなにぃ??
ググリマス。
201196のチラウラ:2007/11/28(水) 15:44:55
202196:2007/11/28(水) 18:05:50
safe bool idiom って boost の中でも使われている
みたいだけど、上のサイトにのってるテンプレートの
コード自体は取り込まれていないの?
203デフォルトの名無しさん:2007/11/28(水) 18:17:56
>>199
basic_ios<>でもoperator boolではなくて
operator void*() constだからな。
ポインタとboolの暗黙の変換を利用して真偽値の判定を行う。

cin >> x;
if(cin) { ... }
204デフォルトの名無しさん:2007/11/29(木) 07:53:55
およそ 500 個の cpp ファイルからなる無駄に汎用的なライブラリの開発に関わってるんですが、
モノシックなヘッダを1つ include すれば使えるようにするのと、
500個のヘッダを必要になるたび一つ一つ include してもらうのと、
あるいは両者の中間と、それぞれどんな長所や短所があるでしょうか?
205デフォルトの名無しさん:2007/11/29(木) 08:33:58
500個のヘッダと、それらをすべてincludeするヘッダを一個作れば問題解決
206デフォルトの名無しさん:2007/11/29(木) 10:11:45
これコンパイルエラー(C2059:構文エラー'{')になるんですけど、どうすればいいですか?
class CHoge
{
static const char Names[][]
{
"Name1",
"Name2",
"Name3"
};
};
207デフォルトの名無しさん:2007/11/29(木) 10:13:30
あ、= 忘れてた。訂正。
class CHoge
{
static const char Names[][]
{ //ここでC2059
"Name1",
"Name2",
"Name3"
};
};
208デフォルトの名無しさん:2007/11/29(木) 10:14:34
やばいテンパッテル。
これが本当の訂正。すまん。
class CHoge
{
static const char Names[][] =
{ //ここでC2059
"Name1",
"Name2",
"Name3"
};
};
209デフォルトの名無しさん:2007/11/29(木) 10:38:59
C/C++では多次元配列で全ての要素数が不定(自動決定)なものは定義できません。
>>208のように、全ての要素(文字列)の長さが一緒になるとしても、です。

static const char Names[][6] = {
  "Name1", "Name2", "Name3",
};
なら通るんじゃないでしょうか(VC++6.0で確認)
210デフォルトの名無しさん:2007/11/29(木) 11:08:03
いや、classのブロックからはずすとコンパイル通るんですよー。

static const char Names[][] =
{ //ここでC2059
"Name1",
"Name2",
"Name3"
};

class CHoge
{
};
これならOK。でもクラスの静的メンバーとして二次元配列を持ちたいんですが、どうすればいいですか?
211デフォルトの名無しさん:2007/11/29(木) 11:42:34
>>210
クラス宣言内に書くのではなく
CPPファイルのほうに書く
212デフォルトの名無しさん:2007/11/29(木) 11:47:39
staticなメンバは、constな整数型に限りクラス定義中で初期化できる。(9.4.2)
213デフォルトの名無しさん:2007/11/29(木) 11:51:33
const staticな整数値以外はクラス内では書けない。
214デフォルトの名無しさん:2007/11/29(木) 11:56:39
かぶった。すまん。
215デフォルトの名無しさん:2007/11/29(木) 13:18:38
引き続きなんですが、どうやったらcppに定義できますか?

Hoge.h
class CHoge
{
static const char Names[3][6];
};

Hoge.cpp
CHoge::Names[3][6] =
{
"Name1",
"Name2",
"Name3"
};

C2373 Namesが再定義されています。とコンパイルエラーになります。
よろしくお願いします。
216デフォルトの名無しさん:2007/11/29(木) 13:49:14
なんでHoge.cppの方に型を書かないの?
217デフォルトの名無しさん:2007/11/29(木) 13:50:20
>>210-231
ソウイウコトダッタノカ。
早とちりすまん。

>>215のコードだと、cppの方に型指定が抜けてる気がするんだが。
正確には
cont char CHoge::names[3][6](以下略
じゃなかろうか。
218デフォルトの名無しさん:2007/11/29(木) 14:02:05
おお、できた!ありがとう!
219デフォルトの名無しさん:2007/11/29(木) 17:53:37
multimap<int, map<long,int> > みたいなコンテナの入れ子ってできるんですか?
220デフォルトの名無しさん:2007/11/29(木) 18:08:37
できるよ
221デフォルトの名無しさん:2007/11/29(木) 19:58:27
int Nanakano::Check()
{
int hensu;
hensu = (int)toaru_kansu();
return (hensu);
}
ってこれ何やってる処理ですか?
222デフォルトの名無しさん:2007/11/29(木) 20:04:03
この、
(int)関数()
ってのがわかんないです。何ですか?これ。
223デフォルトの名無しさん:2007/11/29(木) 20:13:24
すみません。キャスト変換ってやつですね。
toaru_kansu()が long型の関数だから、無理やり int型に変換してるみたいです。
toaru_kansu()の戻り値をintにして返してるだけの関数のようですね。。これ。
224デフォルトの名無しさん:2007/11/29(木) 20:15:24
int Nanakano::Check() {return (int)toaru_kansu();}
225デフォルトの名無しさん:2007/11/29(木) 20:21:06
return
の引数って
()
をつけてもつけなくてもいいんですか?
226デフォルトの名無しさん:2007/11/29(木) 20:22:12
returnは関数じゃないので、引き数なんてありません。
227デフォルトの名無しさん:2007/11/29(木) 20:23:17
むしろ、つけちゃダメ

retrun(0) って関数を呼び出しちゃうときがある
228デフォルトの名無しさん:2007/11/29(木) 20:42:14
>>227
わかりました。ありがとうございます。
>>226
return
のあとの数字をなんというのでしょう?戻し値?
229デフォルトの名無しさん:2007/11/29(木) 20:44:28
coutとかで画面に出力した文字を簡単にファイルに記録することなんてできる?
230デフォルトの名無しさん:2007/11/29(木) 20:47:53
戻り値、返り値、返値

好きなの使え
231デフォルトの名無しさん:2007/11/29(木) 20:52:11
>>229
たとえばこんなのどうでしょ「a.exe > out.txt」

Cならstdoutをファイルでrefopen(こんな名前だっけ?)すればいいけど
iostreamも基本、同じかな?
232デフォルトの名無しさん:2007/11/29(木) 21:07:46
>>231スゲーーーーーーーーーできました。
ありがとうございました。
233デフォルトの名無しさん:2007/11/29(木) 21:22:08
ifstreamクラスでテキストファイルを読み込む際に、
consoleアプリで行った場合には問題なく動くのですが、DLLとして作成すると同じコードなのにファイルの読込に失敗します。
原因わかりませんか?
234デフォルトの名無しさん:2007/11/29(木) 21:25:46
エスパーすると、実行時のパスが違うというオチでは
235デフォルトの名無しさん:2007/11/29(木) 21:30:50
>>234
excel VBAでDLLを読み込んでいるのですが、実行時のパスってどこにあるんでしょう?
exeファイルの場所??
236デフォルトの名無しさん:2007/11/29(木) 21:39:33
>>235
Excelのある場所になるのかのぉ?
悪いこと言わないから絶対パスですればよろし
237デフォルトの名無しさん:2007/11/29(木) 21:39:46
C:\Documents and settings\〜 とか、そのへんの予感
238デフォルトの名無しさん:2007/11/29(木) 21:48:30
作戦1 : ファイルの絶対パスまで含めてみた
 → 変なエラーがたくさんでて終了

作戦2 : パス通してみた
 → 結局読み込めない

がーーー意味がわからないです…。
Consoleでちゃんと読み込めていることにさらに疑問。
239デフォルトの名無しさん:2007/11/29(木) 22:00:23
なめてんのか?
240デフォルトの名無しさん:2007/11/29(木) 22:07:20
>>238
変なエラーってなんだよw
241デフォルトの名無しさん:2007/11/29(木) 22:23:20
>>240
ソースは全部会社にあるので確認ができないわけです…
242デフォルトの名無しさん:2007/11/29(木) 22:41:47
>>230
サンキューサー!!!!
243デフォルトの名無しさん:2007/11/29(木) 23:05:28
>>240
俺のエスパーはたぶん \\ だと告げている
244デフォルトの名無しさん:2007/11/29(木) 23:13:30
うーん・・・

a.cpp
 namespace a
 {

 void func()
 {
 }

 } // namespace a

といった、名前空間内にある関数を、他のファイルから参照する方法は無いんですかね?
名前空間に閉じ込めてなければ、
extern void func();
でいいんですけど…
245デフォルトの名無しさん:2007/11/29(木) 23:17:57
え?
namespace a{ extern void func(); };
でいいんじゃないの?
246デフォルトの名無しさん:2007/11/29(木) 23:25:59
namespace a{ extern void func(); };
で宣言、
a::func();
で使う。
247デフォルトの名無しさん:2007/11/30(金) 03:41:57
>>245,246
(・∀・)ありがとう!

分かってみると単純ですね(´・ω・)お騒がせしました。
248デフォルトの名無しさん:2007/11/30(金) 10:28:07
ラッピングって何ですか?
「この関数はラッピングしてるだけ」ってのは、その関数は別の関数を呼んでるだけで処理をやってない
って意味でしょうか?
249デフォルトの名無しさん:2007/11/30(金) 10:33:03
adapter patternでぐぐれ
250デフォルトの名無しさん:2007/11/30(金) 10:38:39
ある関数をプロトタイプ宣言しているヘッダファイルは見つけたんですが、
そのヘッダファイルを開いても意味不明の構造体が並んでるだけで、
その関数の処理自体がどこにも書かれていません。
この関数はどこにあるのでしょうか?

printf()関数などもそうですが、中身がどこにも書かれてなくても使えるものなのでしょうか?
その場合、その関数の使い方などはどこで知ったらいいですか?
251デフォルトの名無しさん:2007/11/30(金) 10:42:12
>>250
ふつうは、ライブラリの中にコンパイル済みのコードが入っている。
Windowsだと 〜.lib 〜.dll、UNIX だと lib〜.a lib〜.so とか。

使うだけなら、そのソースは必要ない。使い方はマニュアルを読む。
252デフォルトの名無しさん:2007/11/30(金) 10:42:53
static link library
使い方はドキュメント見れとしか言えないね
でも引数と戻り値、概要、例外安全性、計算複雑性(?)等のインタフェースが分かったらそれで使えるでしょ
253デフォルトの名無しさん:2007/11/30(金) 10:49:44
>>251-252
なるほど。.lib や .dll にあるんですね。ありがとうございます。
じゃあ、その関数の中身がソース上どこにもなかったら、外部で作って渡された部分と思って間違いないですね。
254デフォルトの名無しさん:2007/11/30(金) 12:49:44
void Kansu(int karihikisu)
{

}

という関数で、return 文のない関数がありました。
これはどういうことですか?なくてもいいんでしょうか?
255デフォルトの名無しさん:2007/11/30(金) 12:54:57
returnがない場合はコンパイラが勝手にretrunを挿入してくれてると思われ
ただい返り値がvoid以外の場合はコンパイラエラーになると思われ
256デフォルトの名無しさん:2007/11/30(金) 13:04:08
>>255
returnを「挿入」するわけではないので念のため。
インライン展開してしまうかもしれないし、ジャンプに置き換えているかもしれない。
257デフォルトの名無しさん:2007/11/30(金) 13:57:45
関数のスコープ範囲から抜ければ、その関数から呼び出し元に戻るので、
voidの関数においてはreturnを明記しなくても問題ない、処理の途中でreturnさせるなら必要だけど。

環境依存と言語仕様は別じゃない?
returnを書いてある関数がインライン展開される事だってあるだろう。
258256:2007/11/30(金) 14:15:32
>>257
あーまぁ、言いたいのは1行目だけだから。2行目は確かに余計だったかもね。
259デフォルトの名無しさん:2007/11/30(金) 16:36:47
よくは分かりませんが、main()関数だと、retrun文がないとエラーになったような??
なので、main以外の関数では、コンパイラによっては正常にコンパイルでき、あった場合と
挙動になんら変わりはない。ってことで・・・いいんでしょうか・・
260デフォルトの名無しさん:2007/11/30(金) 16:37:42
Windows フォームアプリケーションのソース入りのプロジェクトフォルダを別の環境の
Visual Studio 2005 で呼び込むと、

ソース管理
! プロジェクト○○.vcprojはソース管理下に存在しているようですが、関連付けされた
  ソース管理プラグインがこのコンピュータにインストールされていません。
  このプロジェクトのソース管理は無効になります。

□次回からこのダイアログ ボックスを表示しない(D)
   [ OK ] [ ヘルプ(H) ]


と出て、その後


ソース管理 - データベースにアクセスできません
●一時的に管理なしで作業する(T)
○ソース管理の関連付けのバインドを完全に削除する(P)
   [ OK ] [ ヘルプ(H) ]


と出ます。これはどういう原因で起こっているのでしょう?
261デフォルトの名無しさん:2007/11/30(金) 16:42:25
>>260 続き
この状態で、「一時的に管理なしで作業」し、コンパイルした場合、何か
実行後のファイルに影響が出ますか?
中間ファイルや実行ファイルなどのゴミが混ざっていて、実行後のファイルにはなんの影響も
ないのであれば、コンパイルに必要なファイルだけをあれば教えていただきたいです。

あるファイルはこんな感じ↓です。

└「A」フォルダ
├「Release」フォルダ
│ ├BuildLog.htm
│ ├B.obj
│ ├A.dll.intermediate.manifest
│ ├A.obj
│ ├A.res
│ ├mt.dep
│ └vc80.idb
├A.vcproj.MEX.administrator.user
├A.vcproj.vspscc
├mssccprj.scc
├ReadMe.txt
├resource.h
├StdAfx.h
├vssver.scc
├B.cpp
├A.cpp
├A.def
├A.h
├A.rc
└A.vcproj
262デフォルトの名無しさん:2007/11/30(金) 16:47:39
>>259
そのKansuは戻り値がない(void)が、mainには戻り値がある(int)。
戻り値がある関数は、returnが必須。
戻り値がない関数は、その関数の最後まで実行する場合はreturnが要らない。
263デフォルトの名無しさん:2007/11/30(金) 16:50:10
>>260
スレ違い。VCスレにでもどうぞ。

>>259
main()は一般的に、int main()なので戻り値を「戻さないといけない」のでreturnが必要になる。
但し、c++の場合は省略が許されているし、void main()とした場合には戻せないので必ずしも必要ない。
その他の関数の場合は、voidじゃない限り戻り値を戻すことを明示する為にreturnが必要になる。
264デフォルトの名無しさん:2007/11/30(金) 18:04:55
仮想関数の引数にイテレータを渡したいんですけど、どうすればいいですか?

class Base {
public:
template <class Iterator>
void f(Iterator first, Iterator last)=0;
};

このようなことがしたいんですけど、仮想関数を関数テンプレートにすることができず困っています。
引数を具体的な型にすると、汎用性がなくなってしまうし、う〜ん・・・。
265デフォルトの名無しさん:2007/11/30(金) 18:24:35
>>264
any_iteratorはどう?
266デフォルトの名無しさん:2007/11/30(金) 18:45:19
テンプレートクラスじゃダメなの?

簡単に出来ない理由を説明すると、複数の.cppファイルなどで使われるテンプレート関数の型を、
1ファイルずつコンパイルするコンパイラが認識できないので、仮想関数テーブルが作れないんですよ。
267264:2007/11/30(金) 19:32:32
レスありがとうございます。

>>265
DLしてサンプル見てみました。
これ使って解決できそうです。

>>266
ポリモフィズムしたいので、Baseをテンプレートにできないです。
268デフォルトの名無しさん:2007/12/01(土) 09:39:44
class TestClass {
static int x;
public:
TestClass(); //default constructor
以下略
};

int TestClass::x = 0;

こんなインクルードヘッダを複数の *.cpp ファイルで
インクルードしまくったら,TestClass::x の実体は
それぞれに確保されてしまって,リンカが混乱しますか?
269デフォルトの名無しさん:2007/12/01(土) 10:00:58
やってみろ
270デフォルトの名無しさん:2007/12/01(土) 11:23:56
staticでないメンバ関数のリンク時のアドレスを得る方法はありませんか?

struct A{
 int func();
};
void *p = (void*)&A::func;

手持ちの環境はVC6ですが、キャストできないというエラーが出てしまいます。
static_castやreinterpret_castも試しましたがダメでした。

標準的なプログラムから外れているのは承知しているのですが、リンク時の
アドレスがどうしても必要なのです。(メンバ関数ポインタのアドレス以外の
情報は不要で、アドレスの取得はリンク時に静的に解決したいのです)

最近のC++の仕様的には書きようが無いのでしょうか?
よろしくお願い致します。
271デフォルトの名無しさん:2007/12/01(土) 11:39:27
普通にメンバ関数ポインタを使えばいいのでは?

typedef int (A::*func_ptr)();
func_ptr p = &A::func;
272デフォルトの名無しさん:2007/12/01(土) 11:55:09
unionに入れて取るかだけど、メンバ関数ポインタは条件によっては
8バイトになったり、16バイトになったりするからなー。
273デフォルトの名無しさん:2007/12/01(土) 11:58:10
メンバへのポインタと普通のポインタって
何が違うの?何かの本ではメンバーへのポインタは
相対位置を表すみたいに書いてあったけどよくわからん。
274デフォルトの名無しさん:2007/12/01(土) 11:58:32
staticじゃないんだから実行時に決まるんじゃないの??
275デフォルトの名無しさん:2007/12/01(土) 12:03:11
276デフォルトの名無しさん:2007/12/01(土) 12:09:33
多重継承されたクラスがあったとして、thisポインタの
調整情報なども入れねばならないとか何とか。

一時期のg++は「メンバ関数」を「第一引数が明示的なthisをとる普通の関数ポインタ」
に変換する機能があったけどなー。そんなサンクくらい自分で作れってことかなー。
277デフォルトの名無しさん:2007/12/01(土) 12:24:28
>>270
非staticなメンバ関数へのポインタは通常のポインタとは
違うから、void *p = (void*)&A::func; はエラー。
funcがstaticならvoid *p = &A::func; はOK。
278270:2007/12/01(土) 12:40:40
みなさん御指南ありがとうございます。

>>275 それっぽいプラグマだと思ったのですが、やり方が悪いのか、うまく行きませんでした。
>>276 古いコンパイラだと普通にキャストするだけで取り出せたんですよね。

thisの変位に関する御指摘が複数ありましたが、その辺は無視して
リンク時のアドレスが欲しいんです。

ひと手間増えますが、とりあえずstatic関数経由で逃げることにしました。
ありがとうございます。
279デフォルトの名無しさん:2007/12/01(土) 13:26:31
メンバ関数ポインタが理解できないヘタレか? コイツは。
280デフォルトの名無しさん:2007/12/01(土) 13:31:28
そのアドレスを何に使うんだろうな
281デフォルトの名無しさん:2007/12/01(土) 13:34:43
*uck
282デフォルトの名無しさん:2007/12/01(土) 13:35:14
**ck
283デフォルトの名無しさん:2007/12/01(土) 13:36:27
struct hoge
void f();
};
上から下のようにmem_fn的な使い方なら用途はあると思う。
void hoge_f(hoge& h)
{
h.f();
}
284デフォルトの名無しさん:2007/12/01(土) 13:40:22
それなら静的メンバ関数で十分だろ。
285デフォルトの名無しさん:2007/12/01(土) 13:44:34
bindみたいなの作ろうとしてんじゃね?
286デフォルトの名無しさん:2007/12/01(土) 13:50:13
その用途じゃアドレスだけ取ってもthisを調整できないし仮想関数テーブルも引けないから正しく呼べない気がするが…
動的バイナリ変換とか自己書き換えでもやりたいのかね?でもそれじゃstatic関数を挟んだら意味ないよなぁ
287デフォルトの名無しさん:2007/12/01(土) 14:14:38
俺のエスパー能力で答えると、
たぶん>>278はメンバ関数ポインタが理解できないヘタレ。
そこでこんな関数でも作ってつかってるんじゃね?

class Foo
{
public :

static void func1(Foo *this_ptr /*必要に応じて引数とか*/) ;
static void func2(Foo *this_ptr /*必要に応じて引数とか*/)

} ;

void (*p)(Foo *) ;

Foo foo ;
//どちらかを呼び出す。
p(foo) ;

普通はこうするんだけどな

void (Foo::*p)() ;
(foo.*p)() ;
288デフォルトの名無しさん:2007/12/01(土) 15:25:03
>>287
メンバ関数ポインタと通常の関数ポインタの違いを説明してもらえますか?
289デフォルトの名無しさん:2007/12/01(土) 15:26:58
メンバ関数ポインタの使い方なんか本見りゃアホでもわかると思う。
mem_fun以外でどういうときに役に立つの?
290デフォルトの名無しさん:2007/12/01(土) 16:04:43
>>288
メンバ関数ポインタはメンバ関数を指すポインタ
通常の関数ポインタは通常の関数を指すポインタ
違いは明確
291デフォルトの名無しさん:2007/12/01(土) 16:10:35
>>290
具体例を挙げて、どこが明確に違うのか
説明できますか?
292デフォルトの名無しさん:2007/12/01(土) 16:13:42
メンバ関数を指すポインタと、通常の関数を指すポインタ

違うよね!うん!違うね!
293デフォルトの名無しさん:2007/12/01(土) 16:15:37
メンバ関数と通常の関数の違いもわからないのか?
294デフォルトの名無しさん:2007/12/01(土) 16:20:38
実装上の違いを求めてるんならスレ違いだな
295デフォルトの名無しさん:2007/12/01(土) 16:34:28
メンバ関数だからって面罵するなよ
296デフォルトの名無しさん:2007/12/01(土) 16:51:28
質問なんですが

#include <iostream.h>

int main()
{
int a;
cin >> a;

if(a == 0) cout << "0000" << endl;
else cout << "1" << endl;

return 0;

}

文字を入力されたとき1を返すようにしたいのですが何か良い方法はありませんか?
297デフォルトの名無しさん:2007/12/01(土) 16:55:37
なんかうだうだ話でてるけど、
>>270の場合、ただ単に、
void*型へのメンバ関数ポインタのキャストは禁止されてる。
298デフォルトの名無しさん:2007/12/01(土) 16:56:35
>>291
使うときにthisポインタが必要だからややこしいのが
メンバ関数ポインタじゃないの?

変なこと言ってたらスマン。
299デフォルトの名無しさん:2007/12/01(土) 16:58:10
>>296
何の文字よ。
char a;
cin >> a;
とか?もうちょっと詳しく
300デフォルトの名無しさん:2007/12/01(土) 17:10:41
>> 299
数字以外が入れられたときに1を返すようにしたいです。
例といたしましては abc など 入力された場合 1を返す。
301デフォルトの名無しさん:2007/12/01(土) 17:16:17
>>300
こうか?よくわからんが
int a;
cin >> a;
if(cin) cout << "0000" << endl;
else cout << "1" << endl;
302デフォルトの名無しさん:2007/12/01(土) 17:19:24
>>297
staticならOK。
303デフォルトの名無しさん:2007/12/01(土) 17:27:23
>>301
申し訳ないです。
数字だけの処理をしたいだけで 0の入力がされれば0000を出力し、
それ以外の数字を入力されれば1を返す。
しかし、ユーザーが例外的に文字を入力した時1を返す処理をしたいと
思っています。

数字か文字かを判断できる処理があればと思い質問させていただきました。
304デフォルトの名無しさん:2007/12/01(土) 17:33:37
>>292
どんな顔して書き込んでるの?
305デフォルトの名無しさん:2007/12/01(土) 17:37:58
>>303
if(cin && a == 0) でいいんじゃない
306デフォルトの名無しさん:2007/12/01(土) 17:47:18
>>305できました。
if(cin) これはどういった処理なのでしょうか? 
307デフォルトの名無しさん:2007/12/01(土) 17:49:40
もしcinがtrueならば
308デフォルトの名無しさん:2007/12/01(土) 17:53:50
ストリームの failbit を確認している

不正な入力(例えばintを要求しているのに文字を入力した)があるとストリームに failbit がセットされる
なので failbit を確認すれば過去の入力が正常であったか判る
309デフォルトの名無しさん:2007/12/01(土) 17:54:29
310デフォルトの名無しさん:2007/12/01(土) 19:40:47
>> 307
そうですか。
これは、複数 cin を使った場合一番最後につかったものが
適応されるのでしょうか?
311デフォルトの名無しさん:2007/12/01(土) 19:42:01
いや、クリアされるまでずっとセットされっぱなし
312デフォルトの名無しさん:2007/12/01(土) 19:53:33
>>307
今 書き直しました。
#include <iostream.h>

int main()
{
int a;

cout << "数字を入力してください。" << endl;

while(1){

cin >> a;

if(cin){
if( a == '0') cout << "0000" << endl;
else cout << "1" << endl;
break;
}

else cout << "数字以外が入力されました。 もう一度数字を入力してください。" << endl;
}



return 0;

}

やっぱり無理で 文字が入力されると無限ループになってしまいます。
313デフォルトの名無しさん:2007/12/01(土) 20:03:11
>>312
>>311

あとなんで文字の'0'と比較してるんだ?
314デフォルトの名無しさん:2007/12/01(土) 20:05:22
数字以外の文字を読み込んでないんだから、その文字はずっとcinの中に残りっぱなし、毎回読み取りエラー
315デフォルトの名無しさん:2007/12/01(土) 20:23:42
cin.clear()とかcin.ignore()とか
316デフォルトの名無しさん:2007/12/01(土) 20:25:49
>>314
文字が入力されるともう一度入力させるようにするにはどうすればいいでしょうか?
317デフォルトの名無しさん:2007/12/01(土) 20:26:54
cinの中に残ってる文字を読み捨てて failbit をクリアする
318312:2007/12/02(日) 12:56:23
cinを使わず違うやりかたで誤字入力を回避できる方法はないでしょうか?
319デフォルトの名無しさん:2007/12/02(日) 13:01:51
いったん文字列として読み込んでから
自前で数値か判定すりゃいいやん
320デフォルトの名無しさん:2007/12/02(日) 13:22:39
>>319
isdigit関数とatoi関数で出来ました。
321デフォルトの名無しさん:2007/12/02(日) 15:00:08
>320
どうせなら strtol() とか使えば?
322デフォルトの名無しさん:2007/12/02(日) 15:13:21
>>321
ありがとうございます。 使わせていただきました。
323デフォルトの名無しさん:2007/12/02(日) 15:43:25
std::string( 1, '\0' ) == ""
が false になってしまいます。
std::string( 1, 'a' ) == "a" は成り立つのに、なぜ?
324デフォルトの名無しさん:2007/12/02(日) 16:01:32
>>323
std::string( 1, '\0' )は長さが1だが、""は長さが0だから。
325デフォルトの名無しさん:2007/12/02(日) 17:06:23
>>324
うほっ、ありがとう
326デフォルトの名無しさん:2007/12/02(日) 23:51:15
file.hに
void F1();
void F2(){ puts( "F2" ); };

file.cppに
#include "file.h"
void F1(){ puts( "F2" );}

と書いて、mainを呼んでるmain.oとリンクさせると
F2()が多重定義されてるぼけってエラーが出るんだけど
これどう解決すりゃいいですか?
327デフォルトの名無しさん:2007/12/02(日) 23:55:29
static void F2(){ (ry
328デフォルトの名無しさん:2007/12/02(日) 23:56:36
単にインクルードガードしてないだけじゃない?
329デフォルトの名無しさん:2007/12/02(日) 23:56:55
>>326
普通は.hにはプロトタイプ宣言飲のみを書いて中身は.cに書く。
330デフォルトの名無しさん:2007/12/02(日) 23:58:20
解決方法は>327を始めいくつもあるし
ここで教えるのも簡単なんだろうけど

それよりは#includeというものがどういう操作かちゃんと理解しないと
同じエラーを繰り返すだけだよ。
331デフォルトの名無しさん:2007/12/02(日) 23:59:20
> mainを呼んでるmain.o
ここも変
332デフォルトの名無しさん:2007/12/03(月) 00:21:11
>>328
インクルードガードはしてる。
>>329
.hにプロトタイプ宣言だけするのは普通なんだけど、
ちょっと書きたくなった。
>>static
やってみる。
>>331
何が変なのかわかんね。おせーて
333デフォルトの名無しさん:2007/12/03(月) 00:24:06
>>332
main.oはmainを呼ばない。
334デフォルトの名無しさん:2007/12/03(月) 00:29:55
いや、mainを再帰しているかもしれない!
って、mainの再帰は規格違反だっけか?
335デフォルトの名無しさん:2007/12/03(月) 00:43:17
ぁーごめん。
mainを呼んでるmain.cppをコンパイルってmain.oになった
ってこと。
mainを呼んでるって語弊あったすまん。
336デフォルトの名無しさん:2007/12/03(月) 00:43:55
呼んでる->定義してうr
337デフォルトの名無しさん:2007/12/03(月) 00:54:58
語弊っていうか、正反対。
338デフォルトの名無しさん:2007/12/03(月) 00:55:41
なんでstaticで解決できるんですかこれ。
339デフォルトの名無しさん:2007/12/03(月) 01:49:30
staticじゃなくて無名namespaceかinlineの使用を推奨。
340デフォルトの名無しさん:2007/12/03(月) 01:51:42
>>338
staticにするとコンパイル単位の外からは見えなくなるから
341デフォルトの名無しさん:2007/12/03(月) 13:40:02
コンストラクタの記述について質問なのですが、
 MAT* m_matrix[4]
というMAT型データのポインタ配列のポインタを渡したい場合、呼び出す側は 
 &m_matrix
で呼び出そうとしているのですが、コンストラクタの方の型指定は
どのようにすればよろしいのでしょうか?
( MAT**では通りませんでした)
342デフォルトの名無しさん:2007/12/03(月) 13:47:58
>>341
いいたいことがよくわからないけど、constructor の型を指定したいの?
343デフォルトの名無しさん:2007/12/03(月) 13:55:02
書き方が悪くてすみません・・・
コンストラクタに限らず、引数として
MAT* m_matrix[4]のポインタを渡したい場合
受け側の関数の宣言ではどのように型を記述すればよいのか
お聞きしたかったのです。
344デフォルトの名無しさん:2007/12/03(月) 14:00:23
f(MAT* (*p)[4])
345デフォルトの名無しさん:2007/12/03(月) 14:01:04
戻り値忘れてた

void f( MAT* (*p)[4] );
346デフォルトの名無しさん:2007/12/03(月) 14:13:49
>>345
ありがとうございます。通りました。
347デフォルトの名無しさん:2007/12/04(火) 16:45:38
gnuplotを使うプログラムの質問なのです
現在、C++の値をgnuplotに渡すとき毎回gnuplotが起動します。(正確にはwgnuplotに値を渡している)
これを一回起動したら、以降は起動中のgnuplotに値を渡すのはどうすればいいでしょうか?
348デフォルトの名無しさん:2007/12/04(火) 17:24:31
>>347
それはC++の問題じゃないのでgnuplot関連スレへどうぞ。
349デフォルトの名無しさん:2007/12/04(火) 17:42:37
>>348
やっぱりそうでしたか、gnuplotにいってきます。
ありがとうございました。
350347:2007/12/04(火) 20:47:49
gnuplotではうまくいきそうに無いので
プログラムで何とかしたいのですが

プログラムのループの中のデータを毎回別のファイルに保存したいのですがどうすればいいですか?
例えば
t=0 0.txt , t=1 1.txt , ・・・
のように保存できるでしょうか?
351デフォルトの名無しさん:2007/12/04(火) 20:53:07
>>350
ループ内で毎回openして書き出してcloseすればいいんじゃないか。
352347:2007/12/04(火) 21:07:00
今現在は
fstream EE ( "1.txt" , std::ios::out ) ;
を使って保存しているんですが
この1の部分をどうやって変更すればいいのかがわからないので、質問しました。

ループ内に入れるのはわかるんですが、ファイル名の変更がわかりませんという質問です。
文章が下手ですみません
353デフォルトの名無しさん:2007/12/04(火) 21:08:45
stringstream、strstream、sprintf、snprintf
354347:2007/12/04(火) 21:16:19
こんな便利なのが・・・
>>353 解決しました。ありがとうございます。
355デフォルトの名無しさん:2007/12/04(火) 21:18:24
>>352
ostringstream使えば?


for(int i = 0; i < 10; ++i) {
 ostringstream oss;
 oss << i << ".txt"; //ファイル名作成
 ofstream ofs(oss.str().c_str()); //ファイルオープン
 ofs << "output i = " << i << endl; //ファイルへ出力
 ofs.close();
}
356デフォルトの名無しさん:2007/12/05(水) 02:54:41
コードサイズで質問
aaa()のほうがスタック開放コードが少ない分、コードサイズが小さい?
そもそもスタック開放コードって複数生成されるのですか

int aaa()
{
int ret = 1;
char buf[1024];
if(...) {
ret = 0;
}
// スタック開放コード
return ret;
}

int bbb()
{
char buf[1024];
if(...) {
// スタック開放コード
return 0;
}
// スタック開放コード
return 1;
}
357デフォルトの名無しさん:2007/12/05(水) 04:27:32
>>356
コンパイラにもよるんだろうけど
関数ごとのリターン処理は1箇所でジャンプ(つまりはgoto)で飛んでるものが多いと思う。
スタックの開放コードはスタックポインタを動かすだけだからきわめて軽微。
x86用のVC++2005だとこんなコード。
mov esp, ebp
pop ebp
ret 0
358デフォルトの名無しさん:2007/12/05(水) 08:10:57
>>357
いまどきは mov, pop の代わりに leave ニーモニックを使ってあることも。
なんで enter ニーモニックは使わないんだろう…

スレ違いスマソ。
359デフォルトの名無しさん:2007/12/05(水) 09:30:33
C++の規格書?のreinterpret_cast(5.2.10)を読むと

4段落
A pointer can be explicitly converted to any integral type large enough to hold it.

5段落
A value of integral type or enumeration type can be explicitly converted to a pointer. A pointer converted to an integer of
sufficient size (if any such exists on the implementation) and back to the same pointer type will have its original value;

とあるんですが、整数→ポインタ→整数 と変換した場合は元の値は保たれるのでしょうか?
(explicitly convertの意味が良く分からない・・・厳密な変換とは??)
保たれるとして、"large enough"とか"sufficient size"かを確かめるのは、sizeofでチェックすれば十分でしょうか?

やりたいこと:
他人が提供するC言語で書かれたvoidポインターのコンテナに、
今はヒープに取った整数型をポインタを介して格納しているが
せっかくなのでvoidポインタに直接整数を格納したい。(パフォーマンス上の理由)
360デフォルトの名無しさん:2007/12/05(水) 10:25:40
>>359
>整数→ポインタ→整数 と変換した場合は元の値は保たれるのでしょうか?
処理系依存のはずだから保障はないはず。表示して確認すればよいと思う。
ただ、たいがい同じビットパターンだと思う。

>(explicitly convertの意味が良く分からない・・・厳密な変換とは??)
明示的な型変換という意味。(暗黙では変換不可)
361デフォルトの名無しさん:2007/12/05(水) 10:39:45
BCB6の場合、

const char* p1 = "hoge";
short n1 = reinterpret_cast<short>(p1); // エラー。shortはlarge enough to holdではない。
__int64 n2 = 1 << 30; n2 <<= 30;
const char* p2 = reinterpret_cast<const char*>(n2); // OK。でもn2の上位32ビットは失われる。

この場合、整数が小さすぎる心配はコンパイラに任せれば安心だけど、
大きすぎるほうの心配はしなくちゃいけない、ってことになるね。
362デフォルトの名無しさん:2007/12/05(水) 11:05:13
>>358
enterは遅いから。
363デフォルトの名無しさん:2007/12/05(水) 16:36:40
>>359
その「整数」として、intptr_tやUINT_PTRなどの「ポインタと同サイズの整数型」を使うなら。
364356:2007/12/05(水) 23:54:42
>>357
なるほど、returnの位置に関係なさそうなので、
深く考えないことにします。
365デフォルトの名無しさん:2007/12/07(金) 20:49:59
typedef void (*pfunc)();
void c_func(pfunc func) { func(); }
void cpp_func() { throw 0; }

void hoge()
{
try
 c_func(
}
366デフォルトの名無しさん:2007/12/07(金) 20:56:32
失礼しました。途中で書き込んでしまいました。

C関数は誰かが作ったC言語のライブラリだとします。
以下のようにC関数内でC++例外を投げるのは規格上大丈夫なのでしょうか?

typedef void (*pfunc)();
void c_func(pfunc func) { func(); } // C関数
void cpp_func() { throw 0; } // 例外を投げるC++関数

void hoge()
{
 try { c_func(&cpp_func); }
 catch(int) {}
}
367デフォルトの名無しさん:2007/12/07(金) 21:21:13
>>366
Cの関数から呼び出された中で例外を投げたらどうなるかは未定義。
Cの関数に限らずC++同士でも、別のコンパイラでコンパイルした関数に向けて例外を投げると未定義の動作。

foo.hpp:
void foo();

foo.cpp:
#include "foo.hpp"
void foo(){
throw 0;
}

bar.cpp:
#include "foo.hpp"
int main(){
try{ foo(); }
catch(const int&){}
return 0;
}

foo.cppとbar.cppでコンパイラが違うと、まずい。
2つのコンパイラのmangleが同じでリンク出来たとしても、
何が起こるかわからない。
368デフォルトの名無しさん:2007/12/07(金) 21:29:35
「別のコンパイラでコンパイルした関数に向けて例外を投げると」
ってなんか変な表現だな

とにかく、例外を投げると関数が終了して呼び出し元にどんどん戻るじゃん、
それで他のコンパイラでコンパイルした部分に達すると未定義の動作になるってことね。
369デフォルトの名無しさん:2007/12/07(金) 21:33:18
そういえば未定義って言うけど実際やるとどうなるんだろう
370デフォルトの名無しさん:2007/12/07(金) 21:46:08
鼻から(ry
371デフォルトの名無しさん:2007/12/07(金) 21:47:50
>>369
ハードディスクがゼロクリアされる
372デフォルトの名無しさん:2007/12/07(金) 22:25:51
>>369
17時で帰宅できるようになる
373デフォルトの名無しさん:2007/12/07(金) 22:43:13
#pragmaが未定義だったから、大昔のGccはアドベンチャーゲームを起動したりしたんだぜ?
374デフォルトの名無しさん:2007/12/08(土) 09:05:44
自分で定義した operator[] に他のメソッドからアクセスするには
(*this)[hogehoge]みたいにしなくちゃダメ?
あるいは this->operator[](hogehoge) とか.
もっと見やすい書き方ないかなぁ.

それもこれも this が参照じゃなくてポインタなのが悪い気がする.
しかし参照が仕様に入った時期を考えると仕方ない気もする.
いまさらどうしようもないか.
375デフォルトの名無しさん:2007/12/08(土) 10:31:47
operator[]の中身を別のメンバ関数に移してそっち呼ぶようにしたらいいよ
376デフォルトの名無しさん:2007/12/08(土) 13:46:37
C++ の
for( int i = 0; i < 256; ++i )
って書き方は慣れたし便利だなぁと思うんですが
for( char buf[ 1024 ]; fgets( buf, sizeof(buf), fp ); )
って書き方はどうなんでしょう?
変数のスコープは↑の方向が小さいですが
char buf[ 1024 ];
while( fgets( buf, sizeof(buf), fp ) )
の方が普通ですか?

そもそもfgetsなんか使わねぇよ、ってのは無しでお願いします。
377デフォルトの名無しさん:2007/12/08(土) 14:41:43
コンパイルしたら同じコードになるからどっちでもいい。

ただwhileは条件でループ、forは回数でループってイメージがあるので、
whileの方が違和感がないし、forだと可読性が落ちるように思う。
(ソースを流し読みするときに、一瞬考えてしまう)
378デフォルトの名無しさん:2007/12/08(土) 15:09:28
>>376
for の初期化部分に、単なる変数の定義を入れるのは好ましくない。
スコープを制限したいなら、全体をブレースで囲むほうがいい。
379デフォルトの名無しさん:2007/12/08(土) 15:18:40
>>377, >>378
ありがとうございます。
やはり不自然でしたか...
380デフォルトの名無しさん:2007/12/09(日) 00:02:20
関数オブジェクトについて質問です
関数アダプタを使わない場合、
メンバ変数のない単純な関数オブジェクト(比較オブジェクトとか)は通常の関数で代替できる場合が多いと思うのですが、
その場合に関数オブジェクトを使う利点って何でしょう?
381デフォルトの名無しさん:2007/12/09(日) 00:07:37
>>380
最適化で早く小さくしやすい
382デフォルトの名無しさん:2007/12/09(日) 00:14:02
コンパイラがインライン展開してくれる
とレスしようとしたら既にされてた。
383デフォルトの名無しさん:2007/12/09(日) 00:23:47
>>381-382
ありがとうございます
関数でもinlineをつければインライン展開されうると思うのですが、
それよりも優れているのでしょうか?
384デフォルトの名無しさん:2007/12/09(日) 00:26:16
>>383
通常の関数を渡した場合は、関数ポインタを渡したものとされるので、
インライン展開されにくくなる。しちゃいけないってことはないんだろうけど、
そこまでやってくれるコンパイラは見たこと無いな。
385デフォルトの名無しさん:2007/12/09(日) 00:30:13
関数ポインタの場合はサイズと速度のトレードオフがある
下記の a(b) と a(c) では同じ a がインスタンス化されうるが
インライン化しちゃったらそれができない

template<class X> void a(X x) { x(0); }

inline void b(int){}
inline void c(int){}

void d()
{
 a(b);
 a(c);
}
386デフォルトの名無しさん:2007/12/09(日) 00:30:20
>>384
ああ、そうか、ポインタを経由するから……そこまで頭が回りませんでした

参考になりました
ありがとうございます
387デフォルトの名無しさん:2007/12/09(日) 00:36:38
>>385
なるほど、確かにそういうことも起こりますね

結局はテンプレート関数・クラスを用いる場合に、
関数オブジェクトの方がより限定化された範囲で実体化されるので高速化しやすいってことですね
ありがとうございます
388デフォルトの名無しさん:2007/12/09(日) 11:13:42
コンパイラによるとしか言いようがないかもしれないけど質問。
関数オブジェクトのoperator()と、それを呼び出すコードが別の翻訳単位になった場合、
関数ポインタとどっちが高速になりやすい?
あるいは、あなたならどっちを選択する?

foofunc.h:

struct Foo{
bool operator()(bool cond);
}

foofunc.cpp:
bool Foo::operator()(bool cond){
return !cond;
}

main.cpp:
#include "foofunc.h"
#include <iostream>

int main(){
using namespace std;
Foo f;
cout << f(false) << endl;
}



389デフォルトの名無しさん:2007/12/09(日) 11:29:44
>>388
VC8(VS2005)の結果。
--- main.cpp ---------------------------
#include "foofunc.h"
#include <iostream>

int main(){
using namespace std;
Foo f;
cout << f(false) << endl;
00401000 mov eax,dword ptr [__imp_std::endl (402044h)]
00401005 mov ecx,dword ptr [__imp_std::cout (40203Ch)]
0040100B push eax
0040100C push 1
0040100E call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (402038h)]
00401014 mov ecx,eax
00401016 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (402040h)]
}
0040101C xor eax,eax
0040101E ret
390デフォルトの名無しさん:2007/12/09(日) 12:58:21
w
391デフォルトの名無しさん:2007/12/09(日) 18:16:46
const を外すときは const_cast でよいとして、オーバーロードを解決するために const を付けるのも const_cast でいいんですか?
392デフォルトの名無しさん:2007/12/09(日) 18:45:56
>>391
const_cast は危険なキャストをしてないか調べるときに検索するから、
安全な奴は static_cast にしといてくれたほうがいい。
393デフォルトの名無しさん:2007/12/09(日) 23:45:54
スタック変数用のメモリというのは、
関数に入った時点で全て確保されているものなのでしょうか?
それとも変数の宣言位置まで到達して初めて確保されるものなのでしょうか?
例えば下記のようなコードを書いてしまうと、
getHoge()の呼び出し毎に無駄なスタック領域が確保されてしまうものなのでしょうか?

const Hoge& getHoge()
{
 static Hoge hoge;
 if (hoge.isInitialized()) {
  return hoge;
 }
 // ここでhogeの初期化処理のために変数を大量に使用。
 // 以降、hoge.isInitialized()はtrueを返す。
 return hoge;
}
394デフォルトの名無しさん:2007/12/09(日) 23:49:42
>>393
たいがいの環境では、関数に入った時点で、ローカル変数全部の領域が取られる。
395393:2007/12/09(日) 23:55:26
>>394
即答ありがとうございました。
大人しく初期化用に別関数を設けます。
396デフォルトの名無しさん:2007/12/09(日) 23:56:33
>>393
コードやコンパイラの実装によるだろ。スタックの確保なんて無駄になるって言っても
数命令だろうから気にしないでいいと思うけど、心配ならコンパイル結果のアセンブリ
見ないと確実なことはわからない。
397デフォルトの名無しさん:2007/12/09(日) 23:57:19
>>393
実行時に処理が進むたびに必要な領域を確保するのはコストがかかって仕方ないんじゃない?
プラットフォームによって違うだろうけど、そもそもスタックってプロセス生成時に
あらかじめ決まった仮想アドレス空間を割り当てて、関数呼び出しのたびに領域を割り当てるのではなく
フレームポインタ(?)だかなんだかをずらしていくだけ、というのが多いと思う。

間違ってたら全面的にゴメン。
398デフォルトの名無しさん:2007/12/10(月) 10:11:32
>>393
スタックは予め確保されてます、関数毎に確保されるものではないです。
コンパイラはespレジスタ(SH系だとr15など、スタックポインタを管理するレジスタ)が示すポインタに
ローカル変数を積み重ねる形のコードを出力するだけで、スタック領域はOSの管理となっています。

スタック領域が足りなくなったときの振る舞いはOSによって異なるし言語範囲外なので除外。
399デフォルトの名無しさん:2007/12/10(月) 11:46:36
おまいらそろそろ質問自体が規格の範囲外だということに気づけ

>>398
ヒープとスタックの境界が決められてるだけで確保はされてないだろ
400デフォルトの名無しさん:2007/12/10(月) 13:01:51
確保されていなければ使えないと思うのですが。
「確保」の概念の違いなのかな?
401デフォルトの名無しさん:2007/12/10(月) 13:12:08
>>393
そんな簡単なことでオーバーヘッドになったりしないよう
偉い人はちゃんと考えてくれているので気にしなくていい
402デフォルトの名無しさん:2007/12/10(月) 13:29:11
>>400
staticな変数は確保されているだろうが、一般的な実装では、
auto変数(ローカル変数)は関数がコールされるたびにスタックに積まれる。
そうしなきゃ、再起呼び出しなんてできないよ。

階乗を求める
int kai(int n)
{
 if(n=1)return 1;
 else return n*kai(n-1);
}
の場合、スタックにn回分のローカル変数(とreturn時に戻り先のアドレス)が積まれる。
403400:2007/12/10(月) 15:11:45
いやだから、その「スタック」というやつはプロセス起動時にOSによって
「スタック領域」と言う形で用意されているのではないだろうか、という話。
404デフォルトの名無しさん:2007/12/10(月) 16:21:46
実装の話は他所でやれ
405デフォルトの名無しさん:2007/12/10(月) 17:17:59
>>403
とは限らない。Cランタイムライブラリが_main()とかで初期化する場合もある。
ヒープ食いつぶすとスタック領域に食い込んで、スタック壊す実装系もある。
406デフォルトの名無しさん:2007/12/10(月) 19:40:48
407デフォルトの名無しさん:2007/12/11(火) 00:06:28
STL strings implementations comparison (updated)
http://sourceforge.net/forum/forum.php?forum_id=762922
408デフォルトの名無しさん:2007/12/13(木) 02:47:57
#define private public !!!!!!
409デフォルトの名無しさん:2007/12/13(木) 06:34:37
#define class struct
410デフォルトの名無しさん:2007/12/13(木) 11:03:48
411デフォルトの名無しさん:2007/12/13(木) 19:03:17
好ましくない方法だと聞きましたが
vector<vector<int> > a;
と宣言した領域のたとえばa[1][1]に値を放り込むにはどう書いたらいいのでしょうか?
412デフォルトの名無しさん:2007/12/13(木) 19:04:52
連投ですいません
static vector<vector<int> > a;
の場合ですと直接
a[1][1]=3;
のように書けると自分では思ってるんですが、この場合staticで
全部の値が0だからだと思うんですが、果たして全部ってどこまで
取られているんでしょうか
413デフォルトの名無しさん:2007/12/13(木) 19:38:38
>>412
日本語でおk。
414デフォルトの名無しさん:2007/12/13(木) 19:47:28
というか、ちゃんとresizeしてあげないと未定義動作になるんじゃあ。
415デフォルトの名無しさん:2007/12/13(木) 20:29:16
MSNメッセンジャーなどで見かけるチャットウィンドウ上にURLが張られた場合に
自動的にハイパーリンクにする機能が欲しいのですがどのような関数を使えば
いいのでしょうか
416411:2007/12/13(木) 21:02:37
ありがとうございます
けっきょく
vector<vector<int>* > a;
と宣言し
vector<int> *tmp = new vector<int>;
a.push_back(tmp);
(*a).push_back(x);//xは数値
のようにし
cout << (*a)[0];
のように用いることで解消しました
417411:2007/12/13(木) 21:05:17
またすいません
正しくは右です
(*a).push_back(x); →(*a[0]).push_back(x); 
cout << (*a)[0];  →cout << (*a[0])[0];
418デフォルトの名無しさん:2007/12/13(木) 21:15:38
vector<vector<int> > a(100);
for(n=0;n<100;n++) a[n].resize(100);
とすればOK

a[0][0]からa[99][99]まで使える
419デフォルトの名無しさん:2007/12/13(木) 21:21:00
vector<vector<int> > a(100, vector<int>(100));
420デフォルトの名無しさん:2007/12/13(木) 21:26:32
typedef vector<int> Dint;
vector< Dint > a(100, Dint(100));

とすると、a[]の値をDint(100)型で初期化するって事か
なんかどういう仕組みで確保できるのかわからなったよ
421デフォルトの名無しさん:2007/12/13(木) 21:27:29
一次元のときに数値でしか初期化できないものだと思っていたよ
422デフォルトの名無しさん:2007/12/13(木) 21:28:55
vector< Dint > a(100, Dint(100,-1));
cout<<a[0][0]<<endl;
という初期化も出来るんだね
423デフォルトの名無しさん:2007/12/14(金) 01:08:52
>>419が普通だと思うが、、
424デフォルトの名無しさん:2007/12/14(金) 01:12:39
無名名前空間使ってる?
425デフォルトの名無しさん:2007/12/14(金) 01:22:42
使ってる。
426デフォルトの名無しさん:2007/12/14(金) 21:31:27
ソケットを綺麗にラップしたライブラリがほしい
427デフォルトの名無しさん:2007/12/14(金) 21:38:19
>>425
ファイルスコープの変数に使うくらいしか知らないのですが、
もしよかったらどんな場合に使ったらよいか教えてください。
428デフォルトの名無しさん:2007/12/14(金) 21:42:16
>>426
それはおいらも欲しい。
中途半端に作ったことはあったけどw
429デフォルトの名無しさん:2007/12/14(金) 23:52:09
boost::asio::ip
430デフォルトの名無しさん:2007/12/15(土) 02:48:32
string a;
って、

char a[10];
のように、その変数を固定長にしたい(最大長を制限したい)場合どうするの?

431デフォルトの名無しさん:2007/12/15(土) 02:57:10
気をつける
432デフォルトの名無しさん:2007/12/15(土) 02:58:18
>>429
boost の subversio リポジトリ見てるけど,
最近 asio まわり更新多いね.
433デフォルトの名無しさん:2007/12/15(土) 03:05:41
>>430
具体的に制限を越える操作をしたときに何が起こって欲しいの。例外?
434デフォルトの名無しさん:2007/12/15(土) 03:32:41
>>431 >>433
メモリ使用量固定にしたいと考えたんだけど、
どちらで書くにしても、結局事前のチェックをして
から格納しなきゃならないから、確かに >>431
気を付けるしかないってわけですね

>>433
そっか、仕様として想定した範囲以上のメモリ領域
を使った場合に、例外飛ばすようにしておくのも手ですね。
435デフォルトの名無しさん:2007/12/15(土) 03:38:15
std::sort() について教えて下さい。

std::sort( list.begin(), list.end(), cmpfunc);

みたいにしてソート処理させてみました。
string lhs, rhs とすると、cmp func は、 return (lhs < rhs); のようにしています。
これで数字のソートをさせると
10, 11, 12, 1, 2, 3 が
1, 10, 11, 12 ,2, 3 みたいになっちゃうのですが、1, 2, 3, 10, 11, 12 というように
並べるにはどうするのが良いでしょうか?
436デフォルトの名無しさん:2007/12/15(土) 03:42:26
>>435 atoi
437デフォルトの名無しさん:2007/12/15(土) 06:48:05
struct cmpf {
 bool operator()(const std::string& lhs, const std::string& rhs) const {
  return (atoi(lhs.c_str()) < atoi(rhs.c_str()));
 }
};

std::sort(ls.begin(), ls.end(), cmpf());
438デフォルトの名無しさん:2007/12/15(土) 08:45:14
list って sort メンバ関数を使ってソートするんじゃなかったっけ?
439デフォルトの名無しさん:2007/12/15(土) 08:47:20
そういやそうだな。でも変数名が list なだけで std::list じゃないのかもしれない。
440デフォルトの名無しさん:2007/12/15(土) 10:18:52
>>434
デフォルトのallocatorを継承してmax_sizeだけいじってなんとかならんかね。
441デフォルトの名無しさん:2007/12/15(土) 10:28:08
boost::arrayでは如何?
442デフォルトの名無しさん:2007/12/15(土) 10:57:53
STLの使い方はある程度学習したんですが
STLの構造を理解するのに何か良い学習方法
ありませんか?
特にallocatorあたりが理解できてません。
443デフォルトの名無しさん:2007/12/15(土) 11:42:34
同じものをつくってみる
444デフォルトの名無しさん:2007/12/15(土) 12:47:32
>>442 ソース嫁。
445デフォルトの名無しさん:2007/12/15(土) 13:10:12
>>442
allocator<T>のメンバー関数を理解して、独自のコンテナでも作ってみる。
446デフォルトの名無しさん:2007/12/15(土) 21:48:26
最近C++のいろんな、本読んで勉強してるんだけど
知れば知るほど面白いね
処で参照、引数の参照渡しについて、質問です
引数に関数や、配列等を与える場合は、リファレンスで、組込み型の場合は
値渡しがよいと、認識しているのですが、組込み型の引数が2つ以上の場合でも、
値渡しの方がいいのでしょうか?
例えば
unsigned int Foo( const unsigned int n ) const;

unsigned int Hoge( const unsigned int lhs, const unsigned int rhs ) const;
でも、値渡しの方がベター?
447デフォルトの名無しさん:2007/12/15(土) 21:52:49
スマソ
×unsigned int Foo( const unsigned int n ) const;
○int Foo( const int n ) const;
×unsigned int Hoge( const unsigned int lhs, const unsigned int rhs ) const;
○int Hoge( const int lhs, const int rhs ) const;
unsignedは考えないでください
448デフォルトの名無しさん:2007/12/15(土) 22:04:32
>>446
引数それぞれの型に応じて使い分けるのであって、引数の数でどうなるものでもない。

組み込み方かどうかという区分けもあんまり理論的じゃないね。たぶんサイズに応じた
基準を端折って説明されてたのを見たんだろうけど。
449デフォルトの名無しさん:2007/12/15(土) 22:09:54
引数1つ1つを参照にしても変わらないな
引数をまとめて構造体に入れてそれを参照渡しするなら話は別だが
構造体に入れるときに結局コピーするんだし、

void Foo(long long a, long long b, long long c, long long d){
}

void Bar(long long a, long long b, long long c, long long d){
Foo(a, b,c, d);
}

引数をそのまま別の関数に渡すんなら、まあ両方とも構造体参照渡しにすれば…
(でもそういう場合ってインライン化しちゃうか)
450デフォルトの名無しさん:2007/12/15(土) 22:27:22
>>448
>>449
>>447です
サンクスです、
>引数それぞれの型に応じて使い分けるのであって、引数の数でどうなるものでもない。
なるほど、リファレンスのバイト数:値のバイト数との大小関係を考慮しろってことだね
だとすると、VCとかだと、リファレンスのサイズって何バイトなんだろう?
Effective C++ではint型の場合は参照渡しより、値渡しのほうが良いと書いてあったけど
てことは、リファレンスは32バイト以下なんだろうか?
>構造体に入れるときに結局コピーするんだし
そうですね、構造体ってことは、クラスと同じようなもんだとすると、コンストラクタ、デストラクタが
動くから、そのコストもかかることになりますね。
451デフォルトの名無しさん:2007/12/15(土) 22:33:01
>>447です、またまた、ごめんなさい
変な日本語になったかな?
インスタンスのサイズ>リファレンスのサイズ
の場合、参照渡しが○
インスタンスのサイズ<リファレンスのサイズ
の場合、値渡しが○
ってことが書きたかった(^^;
452447:2007/12/15(土) 22:40:33
#include <iostream>
using namespace std;

int main()
{
 int n = 10;
 cout << sizeof( n ) << endl;
 cout << sizeof( &n ) << endl;
 return 0;
}
あれ?同じサイズだな?
値渡しの優位性は何処なんだろう?
453デフォルトの名無しさん:2007/12/15(土) 22:42:04
値ならレジスタで済むので高速
454デフォルトの名無しさん:2007/12/15(土) 22:45:59
そろそろ、ここはお前の日記帳じゃないといいたい。
>>447
値渡しで一番速いのはCPUの扱うワード長を基準に考えればいいだろう。
まあ、基本型のデータをわざわざ参照にしなくてもいいと思うし。
データのコピーより参照を手繰るほうが早く済みそうなら参照・ポインタを使えばいい。
455デフォルトの名無しさん:2007/12/15(土) 22:54:23
>>447
それと値渡しでconstを指定する意味はない。
456デフォルトの名無しさん:2007/12/15(土) 22:58:33
>>453
なるほど@納得した
>>454
まぁそう言うな、どうせお前も暇なんだろww
さて、スキーリしたので、プログラミング言語C++第3版の
続きよーもうっと
457デフォルトの名無しさん:2007/12/15(土) 23:19:24
>>455
受け取った側でポカミス防げるじゃん.
まぁ渡した側としてはどうでもいいけど.
458デフォルトの名無しさん:2007/12/15(土) 23:22:11
>>445
>>それと値渡しでconstを指定する意味はない。
あ、これね前説が抜けてたけど、
FooやHoge関数内で、引き数をいじって、変えて欲しくなかったからだ
だから意味はあるのよん
459デフォルトの名無しさん:2007/12/15(土) 23:24:09
大抵typedefで組み込み型にも別名つけてて、
元がわかんなくなっちゃって、えいやってconst 参照で渡すように書いちゃうんだけど・・・
460デフォルトの名無しさん:2007/12/15(土) 23:45:46
>>458
int Foo( const int n ) const;
int Foo( int n ) const;

のオーバーロードができなくなるという
問題はあるがな。呼ばれた側で値を変えたく
ないなら組み込み型でもconst int&にするわ。
461デフォルトの名無しさん:2007/12/15(土) 23:54:58
boost::asio::ip って日本語の資料皆無だな
462デフォルトの名無しさん:2007/12/15(土) 23:57:14
>>458
プロトタイプのほうを

int hoge(int n); 

にして、関数を定義してるほうを

int hoge(const int n) { ・・・

すべしって、なんかの本に書いてあったよ。

463デフォルトの名無しさん:2007/12/15(土) 23:59:02
>>462
どこの本だよ
464デフォルトの名無しさん:2007/12/15(土) 23:59:56
>>458
オーバーロードではなく
正確には
int Foo( int n ) const;
が定義できなくなるだった。

>>461
書籍に少し載ってる
465デフォルトの名無しさん:2007/12/16(日) 00:04:19
>>463
ハーブサッターっていう偉人を知ってるか?
466デフォルトの名無しさん:2007/12/16(日) 00:04:58
>>463
C++ Coding Standards
467デフォルトの名無しさん:2007/12/16(日) 00:36:56
>>462
>>447だけど
それは、ないやろ
VS2005だと、error C2511が出るぞ?それとも関数定義のブレスの中で何か
テクニックがあるのかな?
今ちょっと、他の本見てみたら、ピアソンの「C++FAQ第2版」では、
int Foo( const int& n );
オブジェクト変更のポカミスには、これが推奨ってなってるな
468デフォルトの名無しさん:2007/12/16(日) 00:56:29
>>467
VS2005でためしたけど、エラーにならないよ?
469デフォルトの名無しさん:2007/12/16(日) 01:09:25
自分もエラーにはならなかった

int f(int a);

int g()
{
return f(1);
}

int f(const int a)
{
return a+1;
}

class X
{
void f(int a);
};

void X::f(const int a)
{}
470デフォルトの名無しさん:2007/12/16(日) 01:48:31
>>462の非constのintだけを宣言・定義はconst,非constで定義できるって話かと思ったけど、
なんか違う?g++では「error: redefinition of `void A::f1(int) const'」っていわれた。

#include <iostream>
struct A {
    void f1(int n) const;
//    void f1(const int n) const;
};

int main()
{
    A a;
    a.f1(100);
    return 0;
}

void A::f1(int n) const {
    std::cout << "call int";
    n += 200;
}
void A::f1(int const n) const {
    std::cout << "call const int";
    n += 200;
}

471デフォルトの名無しさん:2007/12/16(日) 01:59:22
>>462のこれってどんな利点あるんだ?
>>467のconst参照ならわかるが、コピーのnを変更禁止にする利点うかばないのだが....
472デフォルトの名無しさん:2007/12/16(日) 02:01:18
>>470
void A::f1(int n) const
void A::f1(int const n) const
この二つはオーバーロードできない。
参照、ポインタならできる。
以上。
473デフォルトの名無しさん:2007/12/16(日) 02:01:43
>>471
引数を変更したくないときに便利
474デフォルトの名無しさん:2007/12/16(日) 02:02:18
Exceptional C++
475デフォルトの名無しさん:2007/12/16(日) 02:02:57
>>473
ならば、const int& にすべき。

Exceptional C++
476デフォルトの名無しさん:2007/12/16(日) 02:06:32
>>475
なぜわざわざ参照渡しに???
477デフォルトの名無しさん:2007/12/16(日) 02:07:45
大体>>460はそんなオーバーロードを何のためにするんだ?
478デフォルトの名無しさん:2007/12/16(日) 02:09:43
Any cv-qualifier modifying a parameter type is deleted.
[ Example: the type void(*)(const int) becomes void(*)(int) .end example ]
Such cv-qualifier s affect only the definition of the parameter within the body of the
function; they do not affect the function type.
479デフォルトの名無しさん:2007/12/16(日) 02:30:00
>>477
妄想で答えると、>>460はconst/非constオブジェクト両方受けたいために
オーバーロードしたいんじゃね。

480デフォルトの名無しさん:2007/12/16(日) 02:36:48
宣言非const、定義constなんて言ってる
"C++ Coding Standards" は糞本?
481デフォルトの名無しさん:2007/12/16(日) 02:39:33
const int& にすべきなんて言ってる
"Exceptional C++" は糞本?
482デフォルトの名無しさん:2007/12/16(日) 02:42:14
両方ともハーブサッターだろ
for(;;)とwhile(true)と同じ
483デフォルトの名無しさん:2007/12/16(日) 02:42:28
いいや、いい本
本では、constで定義を薦めてるんではなくて
constの宣言はよしなさいと言っている
484デフォルトの名無しさん:2007/12/16(日) 03:11:21
組み込み型でも、const 参照使え
定義const引数でも、宣言非constに汁
と言ってるようじゃ
ハーブサッターって糞著者だな
485デフォルトの名無しさん:2007/12/16(日) 03:29:44
読みもしないで糞と決めつける奴は糞以下だけど
486デフォルトの名無しさん:2007/12/16(日) 03:44:03
>>485
>>484 を言ってるんだろ
487デフォルトの名無しさん:2007/12/16(日) 04:43:52
>>481
const int&で全部糞扱いですか
488デフォルトの名無しさん:2007/12/16(日) 05:02:46
よくわからんが宣言と定義で型が違うのは気持ち悪い
489デフォルトの名無しさん:2007/12/16(日) 06:10:36
実装の都合をインタフェースに反映させるのはよくないと思う。
490デフォルトの名無しさん:2007/12/16(日) 08:31:35
値渡しの引数を受け取った側でいじるってやらない?
俺はローカルオブジェクトと同じ感覚でちょくちょくいじるんだけど

# f(int)をf(const int &)にするのは時期尚早な不最適化だと思う
491デフォルトの名無しさん:2007/12/16(日) 08:32:56
>>446です
@「関数の引数には値渡し、参照渡しがどっちが効率的なのか?」
という質問に、
A「オブジェクトを予期せずに変更してしまうのを避けるにはどうすべきか?」
という、問題が派生してしまったことにより、議論が混乱しているようなので
ここは一度問題を切り分けて、議論する必要があるね、
@のコンセンサスにかんしては
・値渡しよりはconst参照渡しを使う。そうすれば、一般的に効率的で、スライス問題が起こらない。
・ただし、これらは、組込み型とSTLの反復子・関数オブジェクトには適用されない。これらについては、普通、値渡しが適当。
ということでny
ではAに関して、皆さんの意見を語ってください。
492デフォルトの名無しさん:2007/12/16(日) 09:14:31
>>491
>A「オブジェクトを予期せずに変更してしまうのを避けるにはどうすべきか?」
>という、問題が派生してしまったことにより、議論が混乱しているようなので

関数内でコールもとのオブジェクトを更新を避けたいとき、値渡しかconstの参照/ポインタを
使うことについては異論がないんじゃない?
(一部、混乱している人もいるようだけど。)

今議論していたのはインターフェース(プロトタイプ宣言)で int と引数を宣言しておいて
実装(関数定義)で const int として宣言することの是非ではなかったっけ?
493デフォルトの名無しさん:2007/12/16(日) 09:15:44
コンパイラの最適化によって、const int& で渡すのはintで渡すのと同じ効率になってくれないかな?
そこまで賢くない?
494デフォルトの名無しさん:2007/12/16(日) 11:13:50
>>493
インライン展開するときに実引数によっては可能だと思うよ。
495デフォルトの名無しさん:2007/12/16(日) 11:19:12
引数宣言の直接 const が意味無いから付けない。宣言と定義で見た目が変わると
いやだから定義でも基本的に付けない。でも付けてもいいし、実際に付ける時もある。
496デフォルトの名無しさん:2007/12/16(日) 11:19:42
元の話は、const int& じゃなくて const int だというのに気づいてない人がいるような気がする。

>492
>491 の
>A「オブジェクトを予期せずに変更してしまうのを避けるにはどうすべきか?」
ここでいうオブジェクトはコール元ではなくて関数内でのオブジェクトだと思われ。

C++ Coding Standards では const int って宣言に書くと混乱が発生するので(このスレですら発生してるし)、「やるんだったら」定義につけろってことじゃなかったっけ?

個人的にはまず@によって渡し方を決定、(俺はやらんけど)やりたければ値渡しでも定義側で const つければ?ぐらいの立場だな。

あと、ここまで出てなかったと思うんで挙げておくと、引数の型については Boost call_traits ってのもある。これだと const int になるみたい。
497デフォルトの名無しさん:2007/12/16(日) 11:20:50
#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;

typedef struct {
double x,y;
} _tBullet;

class CBullet
{
public:
void Move( _tBullet *bullet );
};

void CBullet::Move( _tBullet *bullet ) {
bullet->y -= 10.0;
}
498デフォルトの名無しさん:2007/12/16(日) 11:21:25
int _tmain(int argc, _TCHAR* argv[])
{
CBullet CBulletFactory;
vector<_tBullet> vBullet;

_tBullet bullet;
int i;
for( i=0; i<10; i++ )
{
double x = (double)(rand()%64)/10;
double y = (double)(rand()%64)/10;
bullet.x = x;
bullet.y = y;
vBullet.push_back(bullet);
}

vector<_tBullet>::iterator p = vBullet.begin();

while( p != vBullet.end() )
{
CBulletFactory.Move(p); // ここでエラー
p++;
}

return 0;
}

499デフォルトの名無しさん:2007/12/16(日) 11:23:04
上記のコードを利用しているのですが
VC++6.0 では正常にコンパイルされるのですが
VC++Express Edition では
c:\documents and settings\owner\デスクトップ\hoge2\hoge2\hoge2.cpp(43) : error C2664: 'CBullet::Move' : 1 番目の引数を 'std::_Vector_iterator<_Ty,_Alloc>' から '_tBullet *' に変換できません。(新しい機能 ; ヘルプを参照)
with
[
_Ty=_tBullet,
_Alloc=std::allocator<_tBullet>
]
この変換を実行可能なユーザー定義変換演算子がないか、または演算子を呼び出せません。
とエラーになってしまいます。
どうすればエラーを回避できるのでしょうか?
500デフォルトの名無しさん:2007/12/16(日) 11:30:03
エラーの記述そのまんま。VC6.0ではvectorのイテレータはポインタにそのまま変換されたが
最近ではならん。邪道かもしれんがその場しのぎならMove(&*p);
501デフォルトの名無しさん:2007/12/16(日) 11:41:29
>>500
解決しました
しかし &*p って 意味的には同じですよね
ポインタは理解しているのですが、深い部分までは理解してなかったのです。

最近はイテレータはポインタとして変換されないんですね
昔勉強した本によると イテレータはポインタの用に動くと明記されていたので
とても困っていました。

細かくはイコールではないのですね
ありがとうございます。勉強にもなりました。
502デフォルトの名無しさん:2007/12/16(日) 12:38:15
http://pastebin.windy.cx/?page=view&id=1197776126
基底クラスを protected で継承して,一部だけを
public で公開したいと思っています.
基底クラスの operator== を public に宣言しなおしても
派生クラスのインスタンス同士で比較しようとすると
派生クラスのポインタから基底クラスの参照への
キャストがアクセス不能であるといわれます.
なぜでしょうか?
503502:2007/12/16(日) 12:42:32
http://msdn2.microsoft.com/en-us/library/s5480d1f(VS.71).aspx
なぜでしょうか?っていうか,それが C++ の言語仕様だから?
知らんかった.
504デフォルトの名無しさん:2007/12/16(日) 12:45:39
>>502
protected だからに決まってる。

それはそうと、
Base::operator ==;
こんな宣言通るんだな。 using ってつけないとダメかと思ってた。
505デフォルトの名無しさん:2007/12/16(日) 12:50:04
>>501
悪いことはいわん。
先頭をアンダーバーではじめるのはやめとけ。
506デフォルトの名無しさん:2007/12/16(日) 12:51:55
それ以前に typedef struct { ... もやめとけ。
507502:2007/12/16(日) 12:52:12
>>504
ピンポイントで
public:
Base::operator ==;
宣言しているので問題ないと思ってました.

ちなみに比較演算子ではなくて適当な関数だと
public:
Base::foo;
で派生クラスから呼び出せます.
これはよく使っていた機能なんで,比較演算子でもやってみました.
呼び出しより前にキャストが起こるからダメなのか.
508デフォルトの名無しさん:2007/12/16(日) 12:54:02
>>501
> しかし &*p って 意味的には同じですよね
違う。

> 最近はイテレータはポインタとして変換されないんですね
単に一部の古い処理系がvector<T>::iteratorをT*でtypedefしてたせいで偶然コンパイルが通っていただけ。
C++がstrong typedefを持っていないのが原因とも言える。
509デフォルトの名無しさん:2007/12/16(日) 12:55:34
>>502
public派生ではない場合、is a 関係にはならんよ。
つまり、派生型から基底型への暗黙の変換は不可。

d1 == d2 は d1.operator==(d2)の意味だけど、d2をBase型へは
変換できない。
510デフォルトの名無しさん:2007/12/16(日) 12:57:19
>>507 エラーメッセージにそう書いてあるだろ。
511502:2007/12/16(日) 12:58:30
>>509
なるほど,is-a の基本を忘れていました.ちなみに

Derived d1,d2;
Base b1;
assert(d1 == b1);

は問題なく通りました.
d1.operator == (b1) だから当然ですね.
512デフォルトの名無しさん:2007/12/16(日) 12:58:51
>>508 strong typedef は関係ないだろ。実装が普通の typedef 使ってたら同じなんだから。
513デフォルトの名無しさん:2007/12/16(日) 13:00:28
>>506
たまにCのソース弄るせいか結構typedefしちまうんだが
なんか弊害あったっけ?
514デフォルトの名無しさん:2007/12/16(日) 13:06:16
>>513
typedef じゃなくて名無し構造体の弊害として、前方宣言が利かない、
コンストラクタ・デストラクタが書けないってのがある。

名無しじゃなくてもクラス名と typedef 名が違うと前方宣言が使いにくい。
515デフォルトの名無しさん:2007/12/16(日) 13:12:46
>>513
変数名に同じ名前が使えなくなるってのも、あるかな。使わなきゃいいんだけど。
516デフォルトの名無しさん:2007/12/16(日) 14:09:39
>>508
どの本読んで勉強したんですか?
MSDNとか?
参考までに聞かせて
517デフォルトの名無しさん:2007/12/16(日) 14:12:10
>>490
>値渡しの引数を受け取った側でいじるってやらない?

引数名が表す意味と内容が合わなくなるからやめろ
って誰かが言ってた希ガス。
518デフォルトの名無しさん:2007/12/16(日) 14:29:32
>>517
俺もその意見に同意する。後で元の値欲しくなったとき困るから
よっぽど小さい関数でもなけりゃローカル変数にコピーしてから弄る
519デフォルトの名無しさん:2007/12/16(日) 15:05:05
構造体を宣言する際、たいがい2回以上その型を宣言しないのに、今まで、無意識に、癖で
typedefを付けていたんだが、無駄な事だと最近になって分かった
C++歴半年の俺
520デフォルトの名無しさん:2007/12/16(日) 15:56:43
>>481
Exceptional C++ に const int& でのパラメータ私を推奨する記述はなかった

ちなみに、あれは良書
当時、例外安全をあんなに大きく正しく取り扱った本は少なかった
今でも少ないか

古い本なので、今では陳腐化した情報もあるだろうけど
521デフォルトの名無しさん:2007/12/16(日) 16:27:38
アドレス例外を例外で拾いたいんだけどどうしたらいいの?
522デフォルトの名無しさん:2007/12/16(日) 16:43:00
アドレス例外なんてのはC++には無い。
環境依存で拾えるかもしれないが、環境書いてないしスレ違い。
523デフォルトの名無しさん:2007/12/16(日) 16:47:34
CPad for Borland C++Compiler
って配布中止になったんですか?
C++を始めようと思い解説サイトでおすすめ
していたので導入しようとおもったんですが
524デフォルトの名無しさん:2007/12/16(日) 16:50:24
>>522
おk
セグメント違反やアドレス例外が拾えたらラッキーだと思ったんだけど
少なくとも尋常な手段ではそういうOSがらみの例外は拾えないのね。
525デフォルトの名無しさん:2007/12/16(日) 17:18:01
>>524
signalでSIGSEGVをキャッチすればいけるんじゃね?
526デフォルトの名無しさん:2007/12/16(日) 17:25:21
>>523
代わりといっては何だけど
ttp://www.hi-ho.ne.jp/jun_miura/bccdev.htm
527デフォルトの名無しさん:2007/12/16(日) 17:48:03
>>523
公式BBSになんかのってるらしいと聞いた
528デフォルトの名無しさん:2007/12/16(日) 18:18:05
BCC developerが標準環境だろう
529502:2007/12/16(日) 18:19:37
Eclipse CDT じゃだめ?
530デフォルトの名無しさん:2007/12/16(日) 18:41:31
ダメでしょ、cygwinとか必要だし
531デフォルトの名無しさん:2007/12/16(日) 19:20:46
>>526
>>527
どうもです。
早速導入してみます。
532デフォルトの名無しさん:2007/12/16(日) 19:31:25
>504
11.3 Access declarations やね。using ができる前のやつなんで deprecated になってる。
533502:2007/12/16(日) 20:15:42
>>532
げ,ふつうに常用していた.
もう使うのやめよう.
534デフォルトの名無しさん:2007/12/17(月) 00:55:31
typedef struct って何が悪いん?
535デフォルトの名無しさん:2007/12/17(月) 01:04:16
C++では、typedef なしで struct X {}; とするだけで、void foo(X x); とか書けるからだよ。
まぁクラス定義をtypedefありで書かないことを考えれば当然とも言える。
ところで、typedef class X_ { ... } X; はコンパイル通るんだっけ?w
 
536デフォルトの名無しさん:2007/12/17(月) 01:09:02
Cのときに@struct書くのが面倒」だったのを、
せっかく処理系が面倒見てくれてる(struct省略できる)のに
わざわざ旧来の書き方をするのは無駄なんじゃね。
537デフォルトの名無しさん:2007/12/17(月) 01:09:55
>>534
構造体とクラスの区別が付きにくくなるから、ってのもある

>>535
出来る
538デフォルトの名無しさん:2007/12/17(月) 01:50:56
神経衰弱のプログラムってどうやったらいいですかね?
539デフォルトの名無しさん:2007/12/17(月) 01:56:32
カード52枚を格納する配列を作って、
ランダムにソートさせて、
取得したカード2枚を比較するロジックを作って、
一致したら配列のカードが格納されていたところを空にして、
カードがなくなるまでゲームを続ければいけるんじゃね?
540デフォルトの名無しさん:2007/12/17(月) 02:12:08
>>539
なんとなく分かったんですが、
一致しなかった場合に裏返すっていうことできませんよね?
違った場合に裏返すってことをしたいんですが・・・
541デフォルトの名無しさん:2007/12/17(月) 02:14:39
>>540
できるじゃん
最初から裏返しにしておいて、
カードをめくるってアクションのときだけ、
配列にアクセスして、指定されたカードの情報をとって、
それを元にそのカードを表示させる
違ったら、その表示を非表示に変えればいいだけのこと
というか、俺はもう寝る
おやすみ
542デフォルトの名無しさん:2007/12/17(月) 02:18:08
C++ 関係ないな。スレ違い。つづきはここでやるなよ。
↓行け。
スレ立てるまでもない質問はここで 87匹目
http://pc11.2ch.net/test/read.cgi/tech/1196509846/
543デフォルトの名無しさん:2007/12/17(月) 09:10:24
同じ名前のクラスをあるプログラム上に複数実装しなきゃならないとき、ヘッダーでnamespace〜〜ってしていいの?
それともヴァージョンが違うだけでほとんど同じクラスだから、一つにまとめたほうがいいんでしょうか?
544デフォルトの名無しさん:2007/12/17(月) 09:21:51
>>543
なぜ同じ名前にするのかじっくり考える。
545デフォルトの名無しさん:2007/12/17(月) 11:33:10
>>543
できる
546デフォルトの名無しさん:2007/12/17(月) 11:56:10
>>543
状況による。
1.そもそもなぜ同じ名前のクラスがでてくるのか
2.1.が問題ないなら、片方のバージョンを保存しておく必要があるのか(後で使うことがあるのかなど)
547デフォルトの名無しさん:2007/12/17(月) 16:07:46
>>544-556
レスさんくすです。

結局そのクラスは機種依存だったので、一つに纏まりました。
しかし、C++って便利ですね。勉強になりました。
548デフォルトの名無しさん:2007/12/17(月) 22:28:59
学生で、今後のためにC++の勉強をしておきたいのですが、
それにあたって、学習に良いと思われる(書き方がやアルゴリズム良い)
オープンソースのプログラムが何かあれば教えていただきたいです。

今はJavaを主に使っているので、オブジェクト指向も理解してますし、
Cも昔やったのでポインタも問題ないです。
本でC++の文法も少しかじり、あとは生きたコードを見たいのですが、
よいものはありますでしょうか?
549デフォルトの名無しさん:2007/12/17(月) 22:30:19
gcc
550デフォルトの名無しさん:2007/12/17(月) 22:37:52
糞汚ったないソースコードにも触れておいたほうがいいぜ

オープンソースと呼んでいいか分からないが、ソフトバンク・パブリッシングのZIP/LHA本の
ソースコードはキレイだった。
551デフォルトの名無しさん:2007/12/17(月) 22:58:55
void foo(std::size_t len) {
 char a[len];
のようなコードは、C++の言語規格に準拠していますか?
C99だと問題ないらしいですが、C++は?
552デフォルトの名無しさん:2007/12/17(月) 23:01:21
だめ
553デフォルトの名無しさん:2007/12/17(月) 23:04:01
そんなんできようがないな
554デフォルトの名無しさん:2007/12/17(月) 23:05:04
>>548
boost ならお手本にしてもいいと思う
C++の最先端の1つでもある
でも初心者には厳しすぎるか

でも、array なんかはシンプルなのですぐに読める
あと、rational も簡単
変態的なものもあるが簡単なものもあるので、簡単なのから読んでいけば大丈夫だと思う

いちおう世界中で使われてる生きたライブラリ
555デフォルトの名無しさん:2007/12/17(月) 23:05:09
ではC++0xでは?
g++はいまでも通るんだけど。

556デフォルトの名無しさん:2007/12/17(月) 23:07:28
関数に必要なスタックサイズがわかんねー気がするんだが
どうやって解決してるんだろ…
557デフォルトの名無しさん:2007/12/17(月) 23:09:05
C99なコード書いて、逆アセンブルしてみればわかるよ。
または昔のCやC++でalloca使ってもいい。
558557:2007/12/17(月) 23:12:54
>>556
subl $48, %esp
みたいな、即値によるスタックポインタ移動が
movl %eax, 引数で渡された数
subl %eax, %esp
とかになるだけ。
559デフォルトの名無しさん:2007/12/17(月) 23:17:49
標準ではC++03のC部分はC99ではないはず。
C++0xではC99が取り込まれる予定とか。
560デフォルトの名無しさん:2007/12/17(月) 23:18:59
ああなるほど
しかし引数が原因でスタックオーバーフローで落ちるのはなんかデバッグが嫌だな
561デフォルトの名無しさん:2007/12/17(月) 23:20:07
>>549>>450>>554
レスありがとうございます。
今GCCを落としてみているところです。
boostについても調べてみます。
562デフォルトの名無しさん:2007/12/17(月) 23:21:50
>>559
VLAは0xでも採り入れられない予定だとおもった
563デフォルトの名無しさん:2007/12/17(月) 23:26:19
こういう実行時に与えられる値でサイズが変化したりするようなものは
あんまり取り入れて欲しくないなあ。
C++はどこまでも静的であって欲しい
564デフォルトの名無しさん:2007/12/17(月) 23:28:14
>>563
soudane.

http://udrepper.livejournal.com/2006/05/25/ こういうことが起きるからなw
565デフォルトの名無しさん:2007/12/17(月) 23:48:04
自分はVLA欲しい派だな
最大値で確保しておく必要がなくなるから無駄が省けてる感がいい
566デフォルトの名無しさん:2007/12/17(月) 23:50:01
欲しいけど気持ち悪くて使えない派
567デフォルトの名無しさん:2007/12/17(月) 23:50:35
自分ら、C#はやらんのか?
568デフォルトの名無しさん:2007/12/17(月) 23:54:22
allocaやasprintfで十分だよ派

>>567
イラネ。erlangならやるかも。
569デフォルトの名無しさん:2007/12/17(月) 23:59:18
C++は古い、次世代C#かJavaかって言うが
あれに全員が乗り換える未来は想像したくない。

Dなら良い
570デフォルトの名無しさん:2007/12/18(火) 00:03:01
なんでC++はCの良いところは受け継がずCの悪いところだけ受け継いでしまったのか。
なんでC++はコンパイラの実装のしやすさは放置してしまったのか。
なんで?
571デフォルトの名無しさん:2007/12/18(火) 00:04:22
>>570
お前の主観には答えられるのはお前だけ
572デフォルトの名無しさん:2007/12/18(火) 00:07:25
親の遺伝子の悪いところだけ受け継いでしまった感じの質問者だね。
573デフォルトの名無しさん:2007/12/18(火) 00:08:08
誰がハゲやねん!
574デフォルトの名無しさん:2007/12/18(火) 00:08:40
D&Eでも読め
575デフォルトの名無しさん:2007/12/18(火) 00:27:49
>>568
allocaはもうMSにも捨てられてるよ
安全でないというより遅いから
576デフォルトの名無しさん:2007/12/18(火) 00:29:39
>>575
何と比べて遅いんだ?

マシン語命令1-2個で実装される関数もどきが遅くなるはずないんだが。
スタック溢れの判定入れても10命令いかないだろう。
577デフォルトの名無しさん:2007/12/18(火) 00:35:31
>>570
Cの良いところってなんだ?
悪いところは結構思いつくが
578デフォルトの名無しさん:2007/12/18(火) 00:38:09
579デフォルトの名無しさん:2007/12/18(火) 00:44:02
>>575 返答まだー?
580デフォルトの名無しさん:2007/12/18(火) 00:49:13
流れぶった切って質問です。
void* から安全にキャストする方法って存在します?

void*だとdynamic_castは効かないし……static_castはミスると未定義だし……
581デフォルトの名無しさん:2007/12/18(火) 00:52:09
>>580
ない。void*の指し先の先頭1バイトに適当なタグを書いておくくらいか?気休めだが。
boostのanyを使って、void*をエミュレートするといい。
582デフォルトの名無しさん:2007/12/18(火) 00:58:24
void*で失敗ってどんなとき?
アドレスってどれでも32bit何じゃないの?
583デフォルトの名無しさん:2007/12/18(火) 01:01:18
>>582
void*がstruct Xを指しているのに、誤ってstruct Y*にキャストして使ってしまったらまずかろうよ。
584デフォルトの名無しさん:2007/12/18(火) 01:04:29
>>583
void *p; として、(int) pとキャストしても、指すアドレスは変化しないと思うんだけど
コンパイル時に型として通るかどうかだけ何じゃないの?
585デフォルトの名無しさん:2007/12/18(火) 01:08:24
>>584
日本語でどうぞ
586デフォルトの名無しさん:2007/12/18(火) 01:09:11
プログラマが何が入っているかわからなくなってしまう場合があるって言うことか
それならコード書いてる時点で良く確認すればよい
587デフォルトの名無しさん:2007/12/18(火) 01:09:42
>>584
アドレスは変わらないが、XオブジェクトをYオブジェクトとして
アクセスしてしまう。
588デフォルトの名無しさん:2007/12/18(火) 01:13:07
>>586
その理屈だとdynamic_castもassertもいらないな。
コンパイラの警告もいらないし、デバッガも不要だし、OSのメモリ保護ももしかしたらいらないかもしれないな。

・・・お前限定で。
589デフォルトの名無しさん:2007/12/18(火) 01:14:53
>>584
お前は根本的に問題が分かっていない。
>>580はむしろ方が違う場合、実行時に例外でも何でもいいから知らせてくれってタイプだ。
やはり>>581しかないな。
ただし1バイトだと、アラインメントの問題があるから、
たとえば4バイトとか、環境に応じて適切にしたほうがいい。
Boost.Anyを使うならば、なお良い。
590デフォルトの名無しさん:2007/12/18(火) 01:15:14
>>586
MFCのうんこコールバックとか使ったこと無いのか?MFCに限らずコールバック関係は
void*が結構使われたりする。
591デフォルトの名無しさん:2007/12/18(火) 01:16:28
で、>>575は?
592デフォルトの名無しさん:2007/12/18(火) 01:17:27
違うことが予測できているなら、動作がおかしかったらそこを疑えばいいじゃないか?
なんの疑いもしないバグは探すのが困難
593デフォルトの名無しさん:2007/12/18(火) 01:40:17
>>592
実行環境が自動で疑ってくれるほうが楽だとは思わんかね?
594580:2007/12/18(火) 01:50:40
サ〜ンクス >581
やっぱり無いか……

実はboost::anyでこういうのをやろうとしたんだけど上手くいかなかったんで、
なんか回避策は無いかな、と探していたところでした……

class A {};
class AA : public A{};

int main() {
   AA aa;
   boost::any testAA(&aa);
   if (boost::any_cast<A*>(&testAA)) {
      std::cout << "testAA* == A*" << std::endl;
   }
}

anyからアップキャストしたポインタ or 参照を取り出したい、というのが希望です。
anyの実装見る限りは出来そうに無いのですが……
595デフォルトの名無しさん:2007/12/18(火) 01:56:06
Anyはtypeid()を見ているからなぁ。難しいな。
boostスレで効いたら?
596デフォルトの名無しさん:2007/12/18(火) 02:00:02
実行時型情報で、ポインタと同時に種類記録しておけ
アドレスと型をもつクラスでも作れ
597デフォルトの名無しさん:2007/12/18(火) 08:43:40
C++が機能を取捨選択するとはらしくないな。もう手当たりしだいに
なんでもかんでも入れちゃうはしたない言語なんだろ?C++は。
598デフォルトの名無しさん:2007/12/18(火) 08:57:46
残念ながら的外れ
599デフォルトの名無しさん:2007/12/18(火) 09:25:37
x86専用とかJavaVM、.NET用ならいいが、
多くのCPUでコンパイル可能な言語なんて今さら作れないんじゃないかな。

だからC/C++は高級アセンブラとしてずっと残るように思う。
600デフォルトの名無しさん:2007/12/18(火) 15:33:07
GCJはC/C++を高級アセンブラとして使う高級コンパイラってところか
601デフォルトの名無しさん:2007/12/18(火) 17:37:44
>>594
boost::any testAA(static_cast<A*>(&aa));
という手もあるが、今度はAA*として取り出せなくなる罠。
602デフォルトの名無しさん:2007/12/18(火) 17:39:42
C++ は最優先事項が C との完全互換らしい。
新機能の搭載も、まずは C との互換が大前提。

逆に、搭載されていないものは C のシンタックスを破壊するものらしい。
603デフォルトの名無しさん:2007/12/18(火) 18:27:25
>>602
の意見に補足すると、C++のコードは一旦Cのコードに変換される
C++の前進が、C with ClassesとBjarne Stroustrupに命名された由縁である
604デフォルトの名無しさん:2007/12/18(火) 18:57:36
Cとの、というか、過去に書かれたコードの互換性、だと思うが。
仕様変更で古いコードがコンパイル不能にならないように、
あるいは、なったとしてもほとんど無視できる程度になるように配慮している。
以前はCに変換してたけど、今は直接オブジェクト・コードを吐いてるはず。実装依存かな。
605デフォルトの名無しさん:2007/12/18(火) 20:00:22
禿が自分でcfontつくったわけだから、603の言い方は妙な感じがする。
606デフォルトの名無しさん:2007/12/18(火) 23:18:13
現行の C++ 仕様でも C へのトランスレータで実現できるのかな?
607デフォルトの名無しさん:2007/12/18(火) 23:31:47
チューリング完全だからそりゃあできるよ
特に効率も落ちないかもしれないし
608デフォルトの名無しさん:2007/12/18(火) 23:44:04
HaskellでさえCへのトランスレータでできるよ
609デフォルトの名無しさん:2007/12/19(水) 00:04:21
C++のテンプレートでhaskellの文法を作るとか
610デフォルトの名無しさん:2007/12/19(水) 07:56:21
cfront は例外が実装できなくて、開発が止まったと
読んだ記憶がある。
611デフォルトの名無しさん:2007/12/19(水) 14:49:22
SetWindowPosを使い、既に最前面化されている場合は解除、そうでない場合は最前面化という動作を
させたいのですが可能でしょうか?

内部で自分が最前面化したウィンドウを覚えておくのではなく、
最前面化されているかどうかを取得できればいいのですが。
612デフォルトの名無しさん:2007/12/19(水) 17:26:01
それがC++とどういう関係があるのか。
613デフォルトの名無しさん:2007/12/19(水) 18:06:16
それでもC++なら・・・C++ならきっと何とかしてくれる
614デフォルトの名無しさん:2007/12/19(水) 18:42:38
Win32APIは全部Cだな
615デフォルトの名無しさん:2007/12/19(水) 18:43:39
単なるインターフェースにCも糞もあるか
616611:2007/12/19(水) 19:47:59
板違いのようで申し訳ない…
Win32APIいってきます
617デフォルトの名無しさん:2007/12/19(水) 21:53:54
VS2005、MFCです
配列を初期化する場合、コンストラクタの初期化子では初期化できないのでしょうか?
初期化したい内容(値)が決まっていればいいのですが、配列の生成時には決まっていないので
とりあえず、配列の個数だけ""で初期化したいのですが?
具体的には
buff[] = {"","",""};
このような事を、コンストラクタの初期化子で行いたいのですが
618デフォルトの名無しさん:2007/12/19(水) 22:10:39
出来ない
619デフォルトの名無しさん:2007/12/19(水) 22:17:10
>>618
617です
そうですか、あきらめました
620デフォルトの名無しさん:2007/12/19(水) 22:59:49
>>617
出来るからw
621デフォルトの名無しさん:2007/12/19(水) 23:02:06
○○○::□□□
というのは、
クラス::メソッド
と思っていいの?
622デフォルトの名無しさん:2007/12/19(水) 23:08:42
そ れ は 他 人 に 相 談 す る 内 容 な の か
623デフォルトの名無しさん:2007/12/19(水) 23:10:03
>>621
名前空間::型名 かも
624デフォルトの名無しさん:2007/12/19(水) 23:14:29
メソッドってなんですか
625デフォルトの名無しさん:2007/12/19(水) 23:37:26
グーグルにアク禁でも喰らってるのか?
626デフォルトの名無しさん:2007/12/19(水) 23:57:13
>>620
そうなのか、どうやって書いたらええの?
教えてくれろ
627621:2007/12/19(水) 23:59:49
>>625
私へのレスですか?久々に受けたww
いえ、ちょっと覚えるのに楽をしようと思って・・・
628621:2007/12/20(木) 00:01:09
C++を10行ぐらいでまとめて説明してください。
629624:2007/12/20(木) 00:01:18
いや、俺へのレスだろw
C++にはメソッドなんてものはないのだ
630621:2007/12/20(木) 00:08:07
>>623
名前空間::クラス::メソッド
って感じなんでしょうか?それを
public:
やら
private:
の下に書くと、中のメンバを隠したりできて・・・合ってます?
他にCとの重要な違いとかあったら教えてください。
>>629
マジっすか!
動作がメソッドだ。ってC++の入門書にまことしやかに書いてあるけどなぁ。。
厳密に言うと、「 」と呼ぶ、みたいなこと?
631デフォルトの名無しさん:2007/12/20(木) 00:09:05
>>628
10行程度で
意味のある説明が
もらえると
考えてる奴には
とうてい
習得不可能な
言語。

あきらめろ。
632621:2007/12/20(木) 00:13:17
10行で説明できる範囲でいいので!お願いします!
633デフォルトの名無しさん:2007/12/20(木) 00:14:42
私はC++の神髄を発見したが、
それを記すにはこの余白は
あまりにも狭すぎる
634デフォルトの名無しさん:2007/12/20(木) 00:18:19
C++ = C89
+ some improvements
+ // comments
+ clases
+ template meta programming
+ STL
あと3行は任せた
635デフォルトの名無しさん:2007/12/20(木) 00:20:10
>>630
>他にCとの重要な違いとかあったら教えてください。
入門書を読んでいるなら、Cとの違いとか書いてないの?
Cと比較して説明していない本だとしても、Cを理解しているなら自分で違いが分かるだろ。

この手の掲示板は、やる気や向上心ののある人に対しては教えたがりの人があれこれ構ってくれるが、
楽したい、自分で調べる気はない、なんて奴は相手にされない。

いいから、まずお前が持ってる入門書とやらをちゃんと嫁。
それで分からないところがあれば聞きに来い。

>動作がメソッドだ。ってC++の入門書にまことしやかに書いてあるけどなぁ。
オブジェクト指向の言語で一般的にメソッドと呼ばれているものは、C++では関数だ。
C++の規格としては、メソッドと呼ばれるものは存在しない。
636デフォルトの名無しさん:2007/12/20(木) 00:23:52
>>634
+ exceptions
637デフォルトの名無しさん:2007/12/20(木) 00:27:17
C++それ自体の規格が沈黙していたとしても、
C++が継承・包含しているもののほうに「メソッド」は
定義されていると見た方が良い。
638621:2007/12/20(木) 00:31:54
どう頑張っても短期には習得できないことがよく分かりました・・・。
>>635
Cとの違いというか、C++だけの大きな特徴というか・・・
Cを覚えるのだけで疲弊しきってしまってC++を覚えるパワーが・・・・
パワーを蓄えてからまた来ます。失礼しました。
639デフォルトの名無しさん:2007/12/20(木) 01:16:06
>>634
パクリかよw
ダセ
640デフォルトの名無しさん:2007/12/20(木) 01:29:47
>>639
そう、パクリ。
でもいろんな面でほどほどにオリジナル (C)と似ているところもあったから、
付いてくる人間がいた。

ださくても、下手な言語よりはよっぽどましに使える。
641デフォルトの名無しさん:2007/12/20(木) 02:06:18
>>640
挙げた例がパクリかと
642デフォルトの名無しさん:2007/12/20(木) 02:12:17
>>634
+ハゲ
+ヒゲ

さいごの一行を誰か頼む。
643デフォルトの名無しさん:2007/12/20(木) 02:18:00
おまいら、つまらんよ
スレの情報密度が下がる。自重汁
644デフォルトの名無しさん:2007/12/20(木) 05:43:58
>>643
自分のレスの情報量と質はどのくらいに見積もってる?
645デフォルトの名無しさん:2007/12/20(木) 10:08:15
>>630
オブジェクト指向言語でメソッドと呼ばれるものは、
C++では「メンバ関数」って言われてる。
646デフォルトの名無しさん:2007/12/20(木) 10:31:17
麺バカンス・・・それは小麦粉と長期休暇を組み合わせた、全く新しい格闘技である
647デフォルトの名無しさん:2007/12/20(木) 10:52:26
>>646
…風雲黙示録を思いだしたよ。懐かしいなぁ。
648:2007/12/20(木) 13:26:20
よくぞ生き残った わが精鋭たちよ!
649デフォルトの名無しさん:2007/12/20(木) 16:11:48
海外でも"Takeshi's Castle"ってタイトルで結構有名なんだよな。
650デフォルトの名無しさん:2007/12/23(日) 17:52:39
typedef std::vector<int> myvec;
のように関数テンプレートについても短いエイリアスを付ける方法はないでしょうか?
typedef並にスマートな方法を教えてください。
651デフォルトの名無しさん:2007/12/23(日) 17:58:48
>>650
関数テンプレートの呼び出しは、普通はコンパイラによる型の推測(deduction)があるから
typedef的なものは不要なわけで、>>650がどう困っているのかその特殊ケースを晒さない
ことには答えにくい。
652650:2007/12/23(日) 18:03:29
>>651
template <bool b, typename T> T func(T a){} これを
typedef func<true, char> myalias; こんな感じにしたいです。
653デフォルトの名無しさん:2007/12/23(日) 18:05:16
>>652
(1) いまはそれをどう呼んでいるんだ?
(2) func()は特殊化する予定?しない予定?

654650:2007/12/23(日) 18:10:18
>>653
(1) char r = func<true, char>('a'); こんな感じです。
(2) 特殊化する予定は有りません。特殊化するかどうかによって事情が変わってきます?
655デフォルトの名無しさん:2007/12/23(日) 18:11:02
template<typename T>
inline T myalias(T a){
return func<true, char>(a);
}
656デフォルトの名無しさん:2007/12/23(日) 18:14:06
inline char myalias(char a)
{ return func<true,>(a); }
657デフォルトの名無しさん:2007/12/23(日) 18:16:37
>>654
char r = func<true>('a'); と、Tは省略できる。それで我慢したらどうよ。
658デフォルトの名無しさん:2007/12/23(日) 18:28:07
>>655-657
回答ありがとうございます。やはりtypedefのようにはいかないみたいですね。
ラッパー関数を作るか、#define の使用も検討してみます。
659デフォルトの名無しさん:2007/12/23(日) 18:54:27
何故defineを検討するのか理解に苦しむ
660デフォルトの名無しさん:2007/12/23(日) 19:27:06
関数が引数を取るとき、プロトタイプ宣言はどうすればいいんですか?

void JicharaMove(int movable){
}
のようなときなんですけれど…
661デフォルトの名無しさん:2007/12/23(日) 19:28:32
>>660
よくわからんな。そのままだろ。
自分でどうやって、期待した結果と何が違ったのか書いてみれ。
662デフォルトの名無しさん:2007/12/23(日) 19:30:35
void JicharaMove();
とヘッダーでプロトタイプ宣言しているのですが、
Error: 外部シンボル 'JicharaMove()' が未解決
とでてしまうのです
663デフォルトの名無しさん:2007/12/23(日) 19:53:11
intは何処いったんだ
664デフォルトの名無しさん:2007/12/23(日) 19:56:43
intをどうすればいいかが…
665デフォルトの名無しさん:2007/12/23(日) 19:59:06
void JicharaMove(int);
666デフォルトの名無しさん:2007/12/23(日) 20:08:27
おお!ありがとうございます!
667デフォルトの名無しさん:2007/12/23(日) 23:58:42
C言語かC++か分からないのですが、こんな↓構文に出くわしましたorz

for ( counter=counter1=1 ; ; counter++) {
....
}

何者ですか、これは・・・・Orz ここで何が起こってるんですか・・・
668デフォルトの名無しさん:2007/12/24(月) 00:01:44
ループ条件が省略されてるだけ。
常に真として扱われる。
669デフォルトの名無しさん:2007/12/24(月) 00:09:07
最初の部分なら単に
counter = (counter1 = 1)
ってだけだから
670デフォルトの名無しさん:2007/12/24(月) 00:11:35
>>668
for ( int counter=1,int counter1=1 ; counter=1,counter1=1 ; counter++) {
....
}

てな意味でしょうか??(あてずっぽうで書いてます)
671デフォルトの名無しさん:2007/12/24(月) 00:12:23
むしろこう。
for ( counter=counter1=1 ; true; counter++)
672デフォルトの名無しさん:2007/12/24(月) 00:14:49
>>671
すみません、これ↓

counter=counter1=1

が既に分からないです。
counter にも、counter1 にも 1 を代入してるってことでしょうか?
これは C++?
673デフォルトの名無しさん:2007/12/24(月) 00:18:01
>>672
int counter1 = 1:
int counter = counter1;
をまとめたもの。

代入文は代入された値として評価されるから、
printf( "%d\n", ( i = 5 ) );
だと 5 が表示される。
674デフォルトの名無しさん:2007/12/24(月) 00:25:18
>>673
あ、なるほど・・
最初に counter1 に 1 が入って、その counter1 を counter に代入して、、って感じですね。

for ( counter=counter1=1 ; true; counter++)

だと、counter の値は回を重ねるごとにどう変化していき、いつ、この for文は終わるんでしょうか?
675デフォルトの名無しさん:2007/12/24(月) 00:30:08
実行したら無限ループ突入しましたorz
676デフォルトの名無しさん:2007/12/24(月) 00:34:53
そりゃそうだw
677デフォルトの名無しさん:2007/12/24(月) 00:39:21
ステップ実行したら分かりました。
counter1 はずっと 1 のままで、counter だけ永遠に 1 足されて表示
されるんですね。どうもありがとうございました。
678デフォルトの名無しさん:2007/12/24(月) 02:28:21
>667
ついでに言うと、counterとcounter1は前に宣言されているのを流用している。
……こりゃあ、あんまり良いコードじゃないな。
コードの意図が判らんと何とも言えんけど、
- counterとcounter1はループの外で代入した方がいい。
- counterのインクリメントはループのブロックに取り込んだ方が良い。
だとオモ
679デフォルトの名無しさん:2007/12/24(月) 03:46:56
C++の問題で、
・正の整数値を読み込みその桁数を出力する
・1からnまでの和をfor文で求める
この2つがわかりません;;教えてください;;
680デフォルトの名無しさん:2007/12/24(月) 04:27:18
>>679
下、動作未確認。
#include<iostream>
int main(void){
int n;
std::cin >> n;
int sum = 0;
for(int i = 1; i <= n; i++){
sum+=i;
}
std::cout<<sum;
return 0;
}
681デフォルトの名無しさん:2007/12/24(月) 04:29:24
>>679
上、動作未確認。
#include<iostream>
int main(void){
int n;
std::cin >> n;
int digit = 0;
for(;n>0;n/=10){
digit++;
}
std::cout<<digit;
return 0;
}
682デフォルトの名無しさん:2007/12/24(月) 09:52:45
>>679
unsigned nofdigit(unsigned foo) {return unsigned(log(double(foo)) / log(10.)) + 1;}
template<int N>sum1() {return (N + 1) * N / 2;}

つーか、スレ違い。宿題なら宿題スレへ、そうでないなら初心者スレへ。
683デフォルトの名無しさん:2007/12/24(月) 13:05:21
>>679
int sum( int n ) {
for(;n;) {
return n + sum( n-1 );
}
return 0;
}
684デフォルトの名無しさん:2007/12/24(月) 13:29:04
すみません、共変の戻り値について教えて下さい。

struct A {};
struct AA : public A {
   void test() { std::cout << "Test " << std::endl; };
};
struct Base {
   virtual A& data() { static A a; return a; };
};
struct Derived : public Base {
   virtual AA& data() { static AA aa; return aa; };
};
int main() {
   Derived d;
   d.data().test();

   Base* pb(&d);
   //pb->data().test();  // コンパイルエラー
   static_cast<Derived*>(pb)->data().test();
};
ということで、多態して使おうとするとエラーになってしまいます。

こういう使い方はNGなのでしょうか?
685デフォルトの名無しさん:2007/12/24(月) 13:33:54
Aにvirtual void test()持たせればいいんでないの
686デフォルトの名無しさん:2007/12/24(月) 13:36:01
>>684
pb->data()が返す型は、あくまでBase::dataで宣言されたA&。
だからAAのメンバは使えない。
687デフォルトの名無しさん:2007/12/24(月) 14:11:46
void JicharaMove(int);
688デフォルトの名無しさん:2007/12/24(月) 20:32:59
最初のインスタンスが生成される前に
(つまり最初にコンストラクタが呼び出される前に)
静的変数の初期化をしたいよ・・・
689デフォルトの名無しさん:2007/12/24(月) 20:37:44
RTTIって言語仕様なのかライブラリなのかなんか中間的だよね.
typeid は演算子なのに,その返り値のクラスは
#include <typeinfo> で定義されてるんですよね.

まぁそれって sizeof 演算子の戻り値が size_t なのと
似ているのかもしれないけど,それもなんか気持ち悪い気が
するのは俺だけ?
690デフォルトの名無しさん:2007/12/24(月) 20:41:23
>>688
現状でもその要件は満たしているようだが、何が不満なのかね?
691デフォルトの名無しさん:2007/12/24(月) 20:48:08
C# の静的コンストラクタ
Java の静的初期化子のようなものを想定していました
692デフォルトの名無しさん:2007/12/24(月) 21:28:21
悪いが C# や Java のそれらを知らない奴にもわかるように説明してくれないか?
693デフォルトの名無しさん:2007/12/24(月) 21:42:35
>>691
(1)シングルトンパターンを使う
(2)Schwarzカウンタを使う
694デフォルトの名無しさん:2007/12/24(月) 21:47:06
まあ、そもそも単純な初期化なら単にソースコード上で代入すればいいわけだが
695デフォルトの名無しさん:2007/12/24(月) 22:19:33
*stringデータ内の"<br>"を探して'\n'に置き換える
誰か教えてお願い
696デフォルトの名無しさん:2007/12/24(月) 22:40:38
>>695 find, replace
697デフォルトの名無しさん:2007/12/24(月) 23:18:32
boostのソース見てたら、
struct hoge {};
struct hogehoge : virtual hoge {};
ってな書き方してあるんだけど、どういう意味?

継承するときに使えるアクセス指定子は、
public, protected, private
のみだと認識してたんだが
698デフォルトの名無しさん:2007/12/24(月) 23:19:38
>>697 仮想継承
699697:2007/12/24(月) 23:38:51
>>698
なるほど!!
初めて知ったぜ。
サンクス!
700デフォルトの名無しさん:2007/12/25(火) 00:36:12
下記のプログラムを実行したらメモリリーク起こしますか?
(main等は省略)

01 class Test{
02   int *p;
03   unsigned int m;
04 public:
05   Test(unsigned int mm){
06     int (*pp)=new int[mm];         //配列ppを生成
07     p=pp;
08     m=mm;
09     for(unsigned int i=0;i<m;i++)p[i]=0;  //テキトーに値を代入
10   };
11   ~Test(void){
12     delete[]p;                 //配列ppを削除(できてるのか心配)
13   };
14 }x(10);
701デフォルトの名無しさん:2007/12/25(火) 00:41:11
>>700
その一部分を見た限りではメモリリークはしないと思うけど?
702デフォルトの名無しさん:2007/12/25(火) 01:07:17
>>700
コピコンと代入演算子がないのでメモリリークする。
703デフォルトの名無しさん:2007/12/25(火) 01:31:23
コピーも代入もしてないが
704デフォルトの名無しさん:2007/12/25(火) 01:37:27
省略してるところでしてたら
メモリリーク+二重解放だな。
してなければメモリリークしないが。
705デフォルトの名無しさん:2007/12/25(火) 01:46:50
>>700
いまどき見ないソースだな
706デフォルトの名無しさん:2007/12/25(火) 01:51:01
普通は vector 使うからね。
707デフォルトの名無しさん:2007/12/25(火) 02:39:02
>>701-706
ども、ありがとございます。
自分で考えたのでこんなソースは見ないと思う。
vectorは勉強してないからわからないんだ。
708デフォルトの名無しさん:2007/12/25(火) 03:09:23
>>707
安心しろ。>700みたいな心配する暇でvectorくらい使えるようになるから。
709デフォルトの名無しさん:2007/12/25(火) 03:33:50
わたくしC++で一行も書いたことないのですが
STLとかBoostとかの仕様をパッとみると、
スクリプトのようにお手軽でしかも美しいコードが
ネイティブコードでコンパイルできちゃうという
夢のような話に思えてくるんですが、
実際のところどうなんでしょうか。
710デフォルトの名無しさん:2007/12/25(火) 07:43:10
間違ったコードを書いたその瞬間になる前までは、そう思っていていい。
気が付くと、これなんかのスクリプティング言語だろ、と思いたくなるコードになっていることはある。

話は逸れるけど、VC++で#importを使うときもVBS、JSみたいなノリだなあと思う。
711デフォルトの名無しさん:2007/12/25(火) 10:04:37
まあネイティブじゃない、って意味ではx86機械語もCPUの内部で
「評価」されて順番が変わったり無くなったりするわけで。

つまりあらゆる言語はスクリプトなんだよ
712デフォルトの名無しさん:2007/12/25(火) 10:11:00
なんだってー!!ΩΩΩ
713デフォルトの名無しさん:2007/12/25(火) 13:17:32
C++のtemplateの特殊化について質問です。
「基底クラスBaseから派生するクラス全て」という条件で特殊化するにはどうしたら良いでしょうか。
今は派生するクラス全てに対して一つ一つ特殊化しているので一般化したいのです。

サンプル
#include <iostream>
using namespace std;
class Base {
};
class Sub: public Base {
};
template<typename T>
void test(T* tp) {
cout << "T" << endl;
}
template<>
void test(Base* bp) {
cout << "Base" << endl;
}
int main(int argc, char* argv[]) {
test(new Base());// Base
test(new Sub());// T (ここをBaseにしたい)
return 0;
}
714デフォルトの名無しさん:2007/12/25(火) 13:33:49
>>713
そういう特殊化はできないような覚えがあるんだけど、
> void test(Base* bp) {
こいつをテンプレートにしなけりゃやりたいことはできるんじゃね?
715デフォルトの名無しさん:2007/12/25(火) 13:47:39
>>713
boost::mplとboost::type_tritsを使うと簡潔

#include <boost/type_traits/is_base_of.hpp>
#include <boost/mpl/if.hpp>
#include <iostream>

struct Base {};
struct Sub:public Base{};
struct Another{};

struct tag_specialized{};

template <typename T> void test_() {
  std::cout << "T" << std::endl;
}

template <> void test_<tag_specialized>() {
  std::cout << "Base" << std::endl;
}

template <typename T> void test(T*) {
  test_< typename boost::mpl::if_< boost::is_base_of<Base,T>, tag_specialized, T >::type >();
}

int main() {
  test(new Base);
  test(new Sub);
  test(new Another);
}
716デフォルトの名無しさん:2007/12/25(火) 23:06:46
>>713
すぐに加速しちゃうのは嫌いなので、>>714 さんを参考に地道に書いてみました。

#include <iostream>
using namespace std;

struct Another { void foo() { cout << "Another::foo invoked." << endl; } };
struct Base { virtual void bar() { cout << "Base::bar invoked." << endl; } };
struct Sub: Base { void bar() { cout << "Sub::bar invoked." << endl; } };

template <typename Lhs, typename Rhs> struct IsBaseOf {
    struct True {};
    struct False { int i; };
    static const bool result = sizeof(testAssignable(static_cast<Rhs*>(0))) == sizeof(True);
    static True testAssignable(Lhs*);
    static False testAssignable(...);
};

template <bool Cond, typename Then, typename Else> struct If;
template <typename Then, typename Else> struct If<true, Then, Else> { typedef Then result; };
template <typename Then, typename Else> struct If<false, Then, Else> { typedef Else result; };

template <typename T> void test_(T* p) { p->foo(); }
template<> void test_<Base>(Base* p) { p->bar(); }

template <typename T> void test(T* p) { test_< typename If<IsBaseOf<Base, T>::result, Base, T>::result >(p); }

int main() {
    test(new Base());
    test(new Sub());
    test(new Another());
}
717713:2007/12/25(火) 23:15:11
>>714-716
ありがとうございます。
とても参考になりました。
複雑なtemplateは書いたことがなかったのですがこれを期に学習します。
718デフォルトの名無しさん:2007/12/26(水) 00:01:43
>>711
X86においてネイティブは存在しない(全てInterpretative)という意味では概ね同意する。
719デフォルトの名無しさん:2007/12/26(水) 06:49:21
質問です。
左右が反転しているだけで他は同じ処理をする木構造のコードを、
今までは関数へのポインタを使って一つにまとめていました。

 get_right( p ){ return p ? p->r : NULL; } /* 右枝 */
 get_left( p ){ return p ? p->l : NULL; } /* 左枝 */

 hogehoge( p, get_right, get_left ); /* 左側 */
 hogehoge( p, get_left, get_right ); /* 右側 */

 hogehoge( p, right, left ) {
  return left( right( p ) );
 }

このコードの
 left( right( p ) );
という内から外へ読まなければならない部分が個人的には嫌いでした。

最近C++を習い始めて、テンプレートや演算子定義などを使えば
 p->right()->left();
のように左から右に読めるコードが書けるのではないかと思うようになりました。

・左から右に読めるようにする。
 旧 get_right()/get_left() を CNode のメンバ関数にした。
・関数内の左右の意味を反転させる。
 関数テンプレートとファンクタで出来た。

というところまでは試してみたのですが、最後に2つを1つにまとめるところで苦労しています。
どのような解決方法があるでしょうか。
どうぞよろしくお願いします。
720デフォルトの名無しさん:2007/12/26(水) 06:55:14
関数は諦めて引数で分ける。
単純に
p->get(right)->get(left);
とすればできる。
別にCでも書ける。
p->get(p, right)->get(p, left);
ほら。
721デフォルトの名無しさん:2007/12/26(水) 10:21:53
C++なら、普通にメンバ関数ポインタでできると思うけどな

typedef Node* (Node::*getNode)();

Node* hogehoge(Node* n, getNode left, getNode right){
  return n->*left->*right;
}

まあleftとrightの2種類しかないなら、定数で指定でもさせた方が楽だとは思うけど
722デフォルトの名無しさん:2007/12/26(水) 10:25:31
間違えた

typedef Node* (Node::*getNode)();

Node* hogehoge(Node* n, getNode left, getNode right){
return ((n->*left)()->*right)();
}

確かに括弧が多くて嫌だなこれ
723デフォルトの名無しさん:2007/12/26(水) 13:49:38
ちなみにC++だと参照を返すことになると思うから代入も出来るな。
Cだと、、、たぶん綺麗には不可能だな。

C++:
Node *&get(bool left){return left ? m_l: m_r;}
p->get(1)->get(0) = q->get(1);
// O.K.!! p->left->right = q->left; と同じ!

C:
node_t *get(node_t *p, bool bleft){return bleft ? p->right: p->right;}
p->get(p,1)->get(p,0) = q->get(q,1);
/* p->left->right = q->left; の意味だができない、、、 */
724デフォルトの名無しさん:2007/12/26(水) 17:52:56
最初の版からNULLチェックが消えてるな。
Null Object で解決できそうだが。
725デフォルトの名無しさん:2007/12/26(水) 18:41:03
オペレーターオーバーロードについて4つほど質問があります。
どうにも説明しにくいので、(1)〜(3)については次レスに具体的なコードを載せておきます。
コンパイラはbccです。
(1)
template <int N> void operator ()(int x);
上記のような引数による推論ができないタイプのテンプレートオペレータの場合、
どのようにテンプレート引数を指定すればいいのでしょうか。
とりあえずは(3)に示すようなやり方でできるにはできたのですが、もっと自然な記法は無いでしょうか。

(2)
(1)に関して、とりあえず
(object.*(&Class::operator()<5>))(4);のように呼び出したら、
"このコンテキストではオーバーロードの意味が曖昧"と怒られました
どのような状況と曖昧でしょうか?

(3)
最終的にキャストすることでテンプレート引数を指定しつつ呼び出すことはできました。
typedef void (Class::&CP)(int);
(object.*(CP)(&Class::operator()<5>))(4);
が、どういうわけかこれを続けて呼び出すと前のテンプレート引数を引きずってしまいます。
(分かりにくいと思うのでコードを見てください)
何故でしょうか。

(4)
メンバ関数ポインタを宣言する際、
void (Class::*p)(int);のようにやりますが、()よりも::の方が優先順位が高いのだから、
void Class::(*p)(int);とやっても大丈夫かと思ったのですが、ダメでした。
何故でしょうか?
726725:2007/12/26(水) 18:43:28
#include <iostream>
using namespace std;
class Foo{
public:
  template <int N> void func(int n){
    cout << N+n << endl;
  }
  template <int N> void operator()(int n){
    cout << N*n << endl;
  }
};
typedef void (Foo::*FP)(int);
int main(){
  Foo f;
  f.func<6>(8); //14
  f.func<9>(2); //11
//  f<7>(5); ERROR
//  f(5)<7>; ERROR "一致するものが見つからない"
//  f(<7>5); ERROR "構文エラー"
//  (f.*((&Foo::operator()<3>)))(9); ERROR "曖昧"
  (f.*((FP)(&Foo::operator()<3>)))(9); //27
  (f.*((FP)(&Foo::operator()<7>)))(12); //36(84と出て欲しい)
  return 0;
}

お願いします
727725:2007/12/26(水) 18:45:53
すいません、(4)は勘違いでした。
::よりも()の方が優先順位が上ですね
728デフォルトの名無しさん:2007/12/26(水) 19:06:14
>>725
f.operator()<6>(8);
とかじゃ嫌?
729725:2007/12/26(水) 19:10:28
>>728
あ、そんなやり方できたんですね……
何でわざわざメンバ関数ポインタにしたりしてたんだろorz
ありがとうございます。
>>725の(2)と(3)については引き続きお願いします。
730725:2007/12/26(水) 19:28:28
すいません、少し質問を変えます
>>726に示したような状況特有の問題かと思ったんですが、もうちょっと簡単な例でも起こりました。
#include <iostream>
using namespace std;
class Foo{
public:
template <int N> void func(int n){
cout << N << ',' << n << endl;
}
template <int N> void operator()(int n){
cout << N << "." << n << endl;
}
};
typedef void (Foo::*FP)(int);
int main(){
Foo f;
f.func<6>(8); //6,8
f.func<9>(2); //9,2
f.operator()<2>(9); //2.9
f.operator()<10>(-1); //2.-1
f.operator()<100>(3); //2.3
return 0;
}
このように、オペレータに限り最初のテンプレートを引きずってしまいます。
bccのバグでしょうか?
731デフォルトの名無しさん:2007/12/26(水) 19:31:59
VC8,gcc3.4なら正常に動作した
732デフォルトの名無しさん:2007/12/26(水) 19:32:43
VC6にも似たようなバグあったな。
733725:2007/12/26(水) 20:31:52
じゃあこれもバグか……コメントが実行結果で
#include <iostream>
#include <vector>
using namespace std;
template <template <class> class T>
class Foo{
public:
  template <class T> void func(const T &x){
    std::cout << typeid(T).name() << std::endl;
  }
};
template <class> class Hoge{};
int main(){
  Foo<vector> f; //int
  f.func(1); //int
  f.func(2.8); //int
  f.func<double>((double)4.889); //int
  Foo<Hoge> f2;
  f2.func(1); //int
  f2.func(2.8); //double
  f2.func<double>((double)4.889); //double
  return 0;
}
何故か自作クラスではOK
他にdeque,list,stack等で確認
734725:2007/12/26(水) 20:33:17
あ、funcのとこでTが被ってるせいかと思ったけどUにしても同じでした
735デフォルトの名無しさん:2007/12/26(水) 21:36:06
template template parameterっすか・・・
それでもgcc3.4とvc8ではちゃんとにi,d,d,i,d,dになっとりました
多分にバグですね
736デフォルトの名無しさん:2007/12/26(水) 21:45:25
VC6とBCC5.5とgcc2.9は、もはやC89コンパイラ
とでも思ってたほうがいいんでないの。
737デフォルトの名無しさん:2007/12/26(水) 22:02:49
>725 の (2) は解決したの?
738デフォルトの名無しさん:2007/12/27(木) 00:25:44
bccのテンプレート実装は古いから結構なバグ持ちだと思うね。
739725:2007/12/27(木) 01:51:20
>>737
解決してません
忘れてた……
740デフォルトの名無しさん:2007/12/27(木) 05:05:25
C++を習い始めたばかりなのですが本によってデフォルトのコンストラクタやデストラクタの宣言が微妙に違うようです。
古いCでは proc() と proc(void) とでは意味が違ったのですが、C++では同じ意味なのでしょうか?
また、皆さんは実際に自分では何れのスタイルで書いていますか?

style A:
 Class();
 ~Class();

style B:
 Class(void);
 ~Class();

style C:
 Class();
 ~Class(void);

style D:
 Class(void);
 ~Class(void);
741デフォルトの名無しさん:2007/12/27(木) 05:11:59
>>740
C++ では同じ。だから (void) は面倒なだけで書かないほうが多い。
最新の C でも () は (...) と同じだから (void) と書かないといけない。

同じ意味の2つを混ぜるのはありえないので style A がいい。
742デフォルトの名無しさん:2007/12/27(木) 07:00:52
俺は (void) 派。
743デフォルトの名無しさん:2007/12/27(木) 10:23:15
>>739
うわーん。気になって眠れないよぉ。
744デフォルトの名無しさん:2007/12/27(木) 12:30:45
昔、デストラクタにvoidでかいたらエラーになったので、空にしている。今もそうなのかな?
745デフォルトの名無しさん:2007/12/27(木) 13:52:50
質問です。
dynamic_castがよく分かりません。
dynamic_castは実行時に型を調べて変換できるときだけ変換する物、と思っていたのですが、
型を覚えているならvoid*型からだって変換できるはずじゃありませんか?
何故できないんでしょうか。
#include <iostream>
class Base {public:virtual ~Base(){}};
class Derived : public Base {};
class Foo : public Base {};

int main(){
  Base *p[2] = {new Derived, new Foo};
  for(int i=0; i<2; ++i){
    if(dynamic_cast<Derived*>(p[i]) == NULL)std::cout << i <<":FAILED\n";
    else std::cout << i <<":SUCCEEDED\n";
  }
  void *q = new Derived;
//  ↓ERROR 'void' 型は仮想関数をもつクラスとして定義されていない
//  if(dynamic_cast<Derived*>(q) == NULL)std::cout << "void*:FAILED\n";
//  else std::cout << "void*:SUCCEEDED\n";
  return 0;
}
dynamic_castは仮想関数を含む物にしか使えない仕様だから、と言われればそれまでなんですが、
型を覚えていることができるなら、このようなvoid*型からのキャストを安全に行うキャストが存在しうると思うんですが、どうなんでしょうか。
それともそもそも「型を覚えている」わけじゃないんでしょうか?
746デフォルトの名無しさん:2007/12/27(木) 14:26:47
実行時の型の情報は仮想関数テーブルに格納されるので、仮想関数テーブルがないと型を見れない
変換元の型が仮想関数を持つ場合は、仮想関数テーブルの引き方がわかるので大丈夫だが、
void*では仮想関数テーブルがあるのかないのかはっきりしない
もし、本当はない型(例えばint)なのに、あると仮定してアクセスすると、アクセス違反で落ちるかもしれん
そのvoid*がBase*だとわかってるなら dynamic_cast<Derived*>(static_cast<Base*>(q)) とすればいいだろうけど
それすらも不明な状況では無理
747デフォルトの名無しさん:2007/12/27(木) 14:28:46
bccで以下のコードが通らないんですが、何故でしょうか……。
#include <iostream>
#include <typeinfo>

int main(){
  int x;
  const type_info& info = typeid(x);
  std::cout << info.name() << std::endl;
  return 0;
}
>エラー E2304 test.c 6: <定数> 変数 'type_info' には初期化が必要(関数 main() )

お願いします。
748デフォルトの名無しさん:2007/12/27(木) 14:33:50
std::type_info かな?
749デフォルトの名無しさん:2007/12/27(木) 14:34:22
>>746
なるほど、仮想関数テーブルが型情報を調べるキーになるわけですね……ありがとうございます。
ということは>>745みたいな感じでvoid*を通してあらゆるポインタを画一的に扱うには、
typeidを保持しておくvoid*ラッパーでも作ればいいんでしょうか……。
ということで誰か>>747もお願いします。
750デフォルトの名無しさん:2007/12/27(木) 14:35:08
>>748
それだ! できました、ありがとうございます!
こんな簡単なことで悩んでたとは……orz
751デフォルトの名無しさん:2007/12/27(木) 15:05:24
>>749
そんなあなたに boost::any
752デフォルトの名無しさん:2007/12/27(木) 15:13:36
bccで以下のコメントアウト部分が通らないんですが、特殊化時に戻り値を変えることはできないんでしょうか?
#include <iostream>
struct Hoge{};
struct Foo{
  template <typename T> T print();
};
template <typename T> T Foo::print(){
  std::cout << "print function." << std::endl;return T();
}
//↓ERROR 'print<Hoge>()' は 'Foo' のメンバーではない
//template <> int Foo::print<Hoge>(){
//  std::cout << "print function. parameter is Hoge. return int." << std::endl;
//  return 1;
//}
template <> Hoge Foo::print<Hoge>(){
  std::cout << "print function. parameter is Hoge." << std::endl;
  return Hoge();
}
int main(){
  Foo f;
  f.print<int>();
  f.print<Hoge>();
  return 0;
}

>>751
調べてみます。
ありがとうございます。
753デフォルトの名無しさん:2007/12/27(木) 15:37:13
725=752かな?どっちでもいいけど
なんでもかんでも関数テンプレートでする必要はないんだよ?
オーバーロードなどと使い分けろ
boost::typeみたいな型を使ってオーバーロードすればやりたいことはできる。
struct Foo{
  template <typename T> T print(boost::type<T>);
  int print(boost::type<Hoge>);
};
template <typename T> T Foo::print(boost::type<T>){
(略)
}
int Foo::print(boost::type<Hoge>){
(略)
}

int main(){
  Foo f;
  f.print(boost::type<int>());
  f.print(boost::type<Hoge>());
  return 0;
}

戻り値の型をtypename boost::mpl::if_<boost::is_same<T, Hoge>, int, T>::type見たいにすれば特殊化でも戻り値の型を変えられたっけ?
試してないけど
754デフォルトの名無しさん:2007/12/27(木) 15:55:46
>>752
template <typename T> T print();
って宣言されてんだから、どう考えても
(T=intの場合) int print<int>()

(T=Hogeの場合) Hoge print<Hoge>()
にしかならない

もう1個テンプレートクラスかませて
template <typename T> PrintReturn<T>::type print();
として
template<T> class PrintReturn { public: typedef T type; };
template<> class PrintReturn<Hoge> { public: typedef int type; };
とすればいいんじゃないかな
そしたら
(T=intの場合) PrintReturn<int>::type print<int>() → int print<int>()
(T=Hogeの場合) PrintReturn<Hoge>::type print<Hoge>() → int print<Hoge>()
になると思う
755デフォルトの名無しさん:2007/12/27(木) 16:09:34
>>753
そうです、725=752です。
とにかく特殊化では戻り値の型は変えられないってことですね?
boostは全くわからないんですが、ぼちぼち手をつけてみようと思います。
ありがとうございます。

>>754
おお、そんなテクニックが……本当に面白いですねテンプレートは。
ありがとうございます、参考になります。

ついでに質問なんですが、>>752とは違い引数から推論可能なタイプの関数テンプレートで、
ある型について特別バージョンを作りたい時に特殊化を用いるのとオーバーロードを用いることの違いは、
戻り値の型を変えられる、ということ以外には何があるでしょうか?
756デフォルトの名無しさん:2007/12/27(木) 17:22:10
テンプレート関数は、実体化されない限り実体が存在しない。
757デフォルトの名無しさん:2007/12/27(木) 17:27:26
>>755
・メンバ関数テンプレートの特殊化はクラス定義内に書けない(ただしVC++では独自仕様でできる)
・関数ポインタを取得する時
たとえば
template<typename T> void func(T);
があってfunc<Hoge>を特殊化した場合は&func<Hoge>としたときに、特殊化版のアドレスが取れる。
一方オーバーロードの場合は常にテンプレート版のアドレスが取れる。
オーバーロード版のアドレスをとりたい場合はstatic_cast<void(*)(Hoge)>(&func)する。
758デフォルトの名無しさん:2007/12/27(木) 18:17:57
>>756-757
ありがとうございます。
勉強になります
759デフォルトの名無しさん:2007/12/27(木) 19:26:51
とあるインターフェイスなクラスを継承した派生クラスA/B/Cがあるのですが

どうも、ある一つのメソッドだけABCでそれぞれ引数の数が異なる事になりそうです。
こういう場合どのようなインターフェイスを設計すべきでしょうか?

可変長引数を使うか
引数用構造体を用意してその構造体を適切な形にダウンキャストするか
と言う方法を考えてみたのですが、可変長引数もダウンキャストもあまり好ましくないと言う話も聞きます
なにか良い方法があるのでしょうか?
760デフォルトの名無しさん:2007/12/27(木) 19:30:20
引数の数が違うってのは、デフォルト引数使えばいいような話じゃなくて?
761デフォルトの名無しさん:2007/12/27(木) 19:35:40
デストラクタにだけvirtual void をつける人を良く見かけるけどなんで?
かっこいいとでも思ってるの?
762デフォルトの名無しさん:2007/12/27(木) 19:36:33
クラスAでは2個引数を、Bでは3つ、Cは今後展開次第で導入予定で未定です

最大数が決まっていれば必要な物以外にはデフォルト引数を使えば良いのでしょうが・・・


763デフォルトの名無しさん:2007/12/27(木) 19:42:59
画像ファイルフォーマットか何かで、圧縮フォーマットの展開か何かみたいなメソッドなのかな?w
引き数の個数の上限設けるのも難だし、構造体でお茶濁すのが無難じゃないかな。
764デフォルトの名無しさん:2007/12/27(木) 19:54:50
>>759
インターフェースを使うって事は、ABCどのインスタンスか意識せずに
共通の方法で扱いたいってことだろ?
でも引数の数が異なるってことは、そのメソッドはABCの違いを意識しないとダメなんだろ?
ならABCそれぞれで定義すべきじゃないか?
765デフォルトの名無しさん:2007/12/27(木) 19:57:58
>>761
戻り値の型を指定してはいけないだろ
voidであってもエラー
766デフォルトの名無しさん:2007/12/27(木) 21:31:05
>>761
デストラクタに virtual を付けるのにはもの凄く意味がある。
それが分からないのは読んだ本が悪かったんだろうな。
767デフォルトの名無しさん:2007/12/27(木) 21:40:30
>>759
こういうのでどう
class MyInterface {
public:
virtual void setSomethingParameter(const char *name, const char *value);
virtual void doSomething();
};

各派生クラスはnameを見てvalueを好きに解釈する
その設定内容をメンバに保存しておいて、doSomethingで使う
768デフォルトの名無しさん:2007/12/27(木) 21:45:58
というか、
呼び出し引数が違う
→呼び出し側でそれぞれの子クラスを区別する必要がある
→区別できるなら安全にキャストできる
→インターフェース側で対応する必要は無く、ただABCでそれぞれメンバ関数を持てばいい
だろ?
769デフォルトの名無しさん:2007/12/27(木) 21:46:19
デストラクタにvirtualをつけないのは犯罪
770デフォルトの名無しさん:2007/12/27(木) 21:59:10
区別する必要がある時点で、
インタフェイス側で対応すべきものではないな。
771デフォルトの名無しさん:2007/12/27(木) 22:39:20
デストラクタがデフォルトでvirtualじゃないのはC++の犯罪。





とは言えない。
772デフォルトの名無しさん:2007/12/27(木) 23:42:49
>>771
それは
無限には存在しないメモリの犯罪
773デフォルトの名無しさん:2007/12/28(金) 00:12:56
デフォルトデストラクタはヴァーチャルでもいい気がする。
774デフォルトの名無しさん:2007/12/28(金) 00:25:29
>>772
メモリというより実行速度の問題な気がするが。

継承しない事が分かっていて、頻繁にオブジェクトが生成/破棄されるクラスのデストラクタはvirtualにしないこともある。その他virtualにしない理由ってあるかな?
775デフォルトの名無しさん:2007/12/28(金) 00:31:58
ほんの少しでも今後継承を行う可能性があるならvirtual指定しておいて問題ないような
776デフォルトの名無しさん:2007/12/28(金) 00:47:58
継承してもせいぜい機能強化版クラスを作るだけで、まず基底クラスとして使うことはないパターンだってあると思うぞ。
ほとんどの場合、しっかり作りこまれたクラス階層を作るでもなければそっちの方が多いんじゃないか?

でもまぁ、しっかり作りこむつもりのクラス階層に属するクラスならvirtualメンバ関数にはしとくよな。
個人的にはさらにそこでvirtual継承も薦めたいところだが。
777デフォルトの名無しさん:2007/12/28(金) 01:35:04
>>774
ポリモルフィックに使いたくない(使われたくない)
基底クラスのデストラクタはprotectedでvirtualではない
デストラクタにすればいいらしい。
基底クラスのポインタにdeleteされるのを防ぐため。
778デフォルトの名無しさん:2007/12/28(金) 06:12:41
そういやデストラクタって今までずっと public にしてた.
デストラクタを public 以外にするのは >>777 のようなケース?
というか,そもそもデストラクタって勝手に呼び出されるから
アクセス指定という概念がなかった.
779デフォルトの名無しさん:2007/12/28(金) 07:55:17
コンストラクタ/デストラクタを隠蔽しないシングルトンなんて嫌だ。
780デフォルトの名無しさん:2007/12/28(金) 16:49:32
オーバーライドした側の関数にvirtualをつける人良く見かけるけどなんで?
かっこいいとでも思ってるの?
781デフォルトの名無しさん:2007/12/28(金) 18:17:01
>>775
問題ある
virtualは今現在の生成物に影響をもたらすトークンであって
今後の設計の遷移の方針を示唆するコメントではない
782デフォルトの名無しさん:2007/12/28(金) 18:35:39
とはいえ今後の設計の方針を示唆することにも使えるわけだ。
パフォーマンスなんて大したことなんだし、迷ったら付けとくぐらいで問題ない。
783デフォルトの名無しさん:2007/12/28(金) 19:56:24
>>782
>今後の設計の方針を示唆することにも使える
使えないよ
だって今後じゃなくて今かもしれないんだし
784デフォルトの名無しさん:2007/12/28(金) 20:22:16
>>780
一長一短あるんじゃないか?
785デフォルトの名無しさん:2007/12/28(金) 20:59:38
>>783
?
786デフォルトの名無しさん:2007/12/28(金) 22:38:23
>>784
仮想関数だと分かりやすいという利点と、
別にオーバーライドであることを保証してくれないから
typo してもコンパイルエラーが出る訳じゃないから
紛らわしいこともあるという欠点があるな。
787デフォルトの名無しさん:2007/12/28(金) 22:43:24
>>786
あと

struct A { virtual void f(); }

struct B : A { void f(); }

struct C : B { void f(); }

とかなってるときにリファクタリングの結果Aを削除したときなんかは
virtual つけてないと意味がかわるし
788デフォルトの名無しさん:2007/12/28(金) 22:46:29
メイヤーズかサッターは virtual つけるのを推奨してたと思う
789デフォルトの名無しさん:2007/12/29(土) 00:01:20
仮想関数 virtualって、どんなときに使うんですか?
意味はわかったけど、どういう場面で使うべきなのか
イメージがわきません。
790デフォルトの名無しさん:2007/12/29(土) 00:13:03
Template Method パターンが一番イメージしやすいんじゃね?
ttp://www.techscore.com/tech/DesignPattern/TemplateMethod.html

ここでも眺めてみるといいよ。
ttp://www.techscore.com/tech/DesignPattern/
791デフォルトの名無しさん:2007/12/29(土) 01:47:42
クラスの機能を拡張するために継承する時、
基底クラスのコンストラクタが呼ばれるのが邪魔な場合がある。
そういう時、基底クラスに何もしない protected なコンストラクタを用意して、
派生クラスではその何もしないコンストラクタを呼ぶようにするといいのではと思った。
こういう手はよく使われるのだろうか?
792デフォルトの名無しさん:2007/12/29(土) 01:53:08
基底クラス弄れるなら何だって出来るような。
793デフォルトの名無しさん:2007/12/29(土) 01:55:12
コンストラクタ内だと仮想関数がうまく働かないってのが問題なんだよな。こういう時。
まあ当たり前の動作なんだが、コンストラクタの処理を変更したい時には困る。
794デフォルトの名無しさん:2007/12/29(土) 08:48:50
>>791
オブジェクトを生成されたくないなら
protectedにするのはコンストラクタではなく
デストラクタでいいだろ
795デフォルトの名無しさん:2007/12/29(土) 08:53:02
newできる
796デフォルトの名無しさん:2007/12/29(土) 09:04:23
>>794
チガウチガウ。
クラス A と、そのバージョンアップ版 A2 を作りたい時の話ネ。
797デフォルトの名無しさん:2007/12/29(土) 09:57:06
皆さん、CSVをパースしたいしたいときは、どうしてますか?
環境はlinux上のg++です。
798デフォルトの名無しさん:2007/12/29(土) 11:21:54
>>797
,を\0に置換してる
799デフォルトの名無しさん:2007/12/29(土) 11:46:35
>>798
痴漢すると何かいいことがありますか?
800デフォルトの名無しさん:2007/12/29(土) 11:49:07
面白くないよ
801デフォルトの名無しさん:2007/12/29(土) 11:49:02
>>799
CSVをパース出来ます
802デフォルトの名無しさん:2007/12/29(土) 11:58:10
自作パーザに食わせてる
803デフォルトの名無しさん:2007/12/29(土) 12:28:21
基底で virtual なものは派生でも virtual つけないと
ダメっていう言語仕様にしてほしかった・・・・・
804デフォルトの名無しさん:2007/12/29(土) 13:44:47
>>803
その仕様はダメ。
関数名を typo しても通るから。
override ってのを付けさせる言語があるけど、
そういう奴の方が安全。
805デフォルトの名無しさん:2007/12/29(土) 15:23:00
C# だったっけ?
使ったことないけど
806デフォルトの名無しさん:2007/12/29(土) 15:46:54
C#といえば最近回りの人間がよく勧めてくるけどそんなに良いのかな?

807デフォルトの名無しさん:2007/12/29(土) 15:48:17
>>795
newしたらdeleteするのは当然
そしてdeleteでコンパイルエラー
もしdeleteを忘れたなら別次元の致命的エラー

>>796
そういう話ね
808デフォルトの名無しさん:2007/12/29(土) 15:49:31
>>806
オライリーの本読んだだけだけど
.NetやるならC++/CLIよりははるかに使いやすい
と思った
809デフォルトの名無しさん:2007/12/29(土) 15:50:20
>>806
言語的にはいいけど、ネイティブじゃないからなあ。
まあ、そのあたりはトレードオフなところもあるから仕方が無いが。
810デフォルトの名無しさん:2007/12/29(土) 17:39:46
>>808-809
そっか、言語の素性はいいのか
windows環境なら別に.netだからと困ることもないし(´-`)
要は使い分けってこった
811デフォルトの名無しさん:2007/12/29(土) 17:44:24
ネイティブじゃないから敬遠してたけど
ネイティブじゃないと何か困ることはあるのかと言えば
速度以外にほとんど無いからね

ちゃんと作れば普通に速いし、ほんとに遅くて困った時
ボトルネックなとこだけ何とか出来るように設計すればいい
812デフォルトの名無しさん:2007/12/29(土) 17:52:03
C# 1.0 はテンプレートがなくてげんなりしたけどな。
2.0 で良くなった。
813デフォルトの名無しさん:2007/12/29(土) 18:45:07
俺は C++ でコアを書いて C++/CLI のラッパーを用意してる.
あとは見栄え良くアプリにするチームが C# でアプリにしてる.
814デフォルトの名無しさん:2007/12/29(土) 19:00:26
まあそんなところが賢い使い方だな。
815デフォルトの名無しさん:2007/12/30(日) 00:40:03
下のコードがVC6では動いたのに、VC2005ではerror c2664で”1 番目の引数を 'std::_Vector_iterator<_Ty,_Alloc>' から 'const POINT *' に変換できません”ってでます。どうすりゃいんでしょう?
std::vector<CPoint> p;
pDC->Polyline(p.begin(), p.size());
816デフォルトの名無しさん:2007/12/30(日) 00:44:25
p.begin()

&p.begin()[0]
817デフォルトの名無しさん:2007/12/30(日) 00:49:23
&(*p.begin())
&p[0]
&p.at(0)
&p.front()
818デフォルトの名無しさん:2007/12/30(日) 07:44:14
******* ヘッダーファイルの定義(一部) *******************
struct List{
char c_Data[100];
double *d_Value;
int i_Priority;
struct List *next;
struct List *prev;
};

******* C++ ソースコード *****************************
bool AddFunction(struct List *pt_List, int i_AddSum, double *pd_AddData)
{
int i_Cnt;
unsigned long ul_ErrorNo;

try
{
if(pt_List->prev->prev == NULL || pt_List->prev == NULL)
{
// err
return false;
}
}
}

ここで、if(pt_List->prev->prev == NULL || pt_List->prev == NULL)が分からないのですが。
ポインタ2つをたどって行った先がnullかどうか、又はprevがnullかどうかを判断しているので
しょうか。
819デフォルトの名無しさん:2007/12/30(日) 08:39:56
>>818
そうだと思うよ。でもそのコードだと後ろの(pt_List->prev == NULL)の意味がない。
もし必要なら逆にしないと。
if(pt_List->prev == NULL || pt_List->prev->prev == NULL)
820デフォルトの名無しさん:2007/12/30(日) 11:38:30
>>804
delphiがそれだね。間違いがなくなって楽。
あと、delphiのinheritedで派生もとのメソッドを呼べるのも間違いがなくなって便利だ。C++で似たようなことができる技ってないかな。

>>806
C#はネイティブコード出力で、Windows以外でもサポートされるようになったら使いたいな。
821デフォルトの名無しさん:2007/12/30(日) 13:23:12
>>820
自分でtypedef 親クラス inherited;とでも書けばいいから、
C++には要らないというのが委員会の結論。

D&E 13.6 Inherited::
822デフォルトの名無しさん:2007/12/30(日) 13:40:04
>>821
おお、その通りだ。早速使わせてもらうよ。
823デフォルトの名無しさん:2007/12/30(日) 13:45:41
でもそれジェネリックには書けないよね。
typedefする箇所で自分の親を知っていないとダメ。
824デフォルトの名無しさん:2007/12/30(日) 14:00:57
クラス内で宣言すればいいじゃん。
825デフォルトの名無しさん:2007/12/30(日) 14:17:46
テンプレート引数Tに対して、typename T::inheritedを使いたければ、
テンプレートを使う側に、inheritedを定義しておけと要求しておけばいい。
826デフォルトの名無しさん:2007/12/30(日) 14:22:43
基底クラスを変更した時に inherited の定義を変更し忘れると悲惨だな。
でも、C++ は多重継承ができるから inherited を言語仕様に入れるのは無理だと思う。
827デフォルトの名無しさん:2007/12/30(日) 14:23:55
>>823
とりあえず、親クラスを変更したときに修正を忘れないように、一番先頭で宣言することにするかな。
privateで宣言しておけば余計な副作用もないかな。

言語仕様に含まれてるのが一番楽とはおもうけど。
828デフォルトの名無しさん:2007/12/30(日) 15:04:30
すれ違いを覚悟して書くと、MS拡張で __super が使えまする。
829デフォルトの名無しさん:2007/12/30(日) 15:12:16
>>826
提案では、inheritedを使うと曖昧になるときはコンパイルエラーだった。

D&Eに載っていた例。
struct A { virtual void handle(int); };
struct B { virtual void handle(int); };
struct D : A, B { void handle(int); };

void D::handle(int i)
{
    A::handle(i); //曖昧でない
    inherited::handle(i); // 曖昧
}
830デフォルトの名無しさん:2007/12/30(日) 16:04:46
QtってC++でしたっけ?
831デフォルトの名無しさん:2007/12/30(日) 16:44:16
俺も多重継承があるから自前で
typedef hogehogehogehogeho Base;
とかする方がいいと思うな.

とりあえず auto 早く来〜い
832デフォルトの名無しさん:2007/12/30(日) 17:17:50
そこでboost::typeofですよ
833デフォルトの名無しさん:2007/12/30(日) 18:58:25
プログラムのある部分にprintfすると正常に動作するのに
そのprintfをなくすとハンドルされてないエラーとかでてくるのはなんででしょうか?
しかも書き込む文字列を変化させてもエラーがでます・・・
834デフォルトの名無しさん:2007/12/30(日) 19:00:55
>>830
MOCで処理するけどな
835デフォルトの名無しさん:2007/12/30(日) 19:15:41
>>833
サンプルコードぷりーず
836833:2007/12/30(日) 19:42:15
すいません。なんかいつの間にか直りました・・・
ただ今度はオブジェクトをdeleteするとエラーが・・・
ソースは長いのですこしはしょります↓


for(){

MIntegralImage *img = new IntegralImage(src_img);
//imgを用いた処理
delete img;

}

5回目でなぜかエラーになります。
837デフォルトの名無しさん:2007/12/30(日) 19:42:21
>>828
お!それは便利だ。でもMS仕様か残念。
最低限gccとintelC+で使えれば良いのにな。
838デフォルトの名無しさん:2007/12/30(日) 19:47:53
>>836
スレ違い。初心者スレにでもどうぞ。
839デフォルトの名無しさん:2007/12/30(日) 21:25:07
>>836
コードを見ないとはっきりしたことはいえないけど
多分スタックを破壊している
840デフォルトの名無しさん:2007/12/30(日) 21:43:59
>>836
deleteが原因ではないと思うです。
VCでdebugビルドなら、newされたオブジェクトのメモリをダンプしながら実行して、オブジェクトの前後のパディングされてるのが壊されてないか見ると良いです。
841833:2007/12/30(日) 21:53:23
空のプロジェクトから作成したせいかどうかわかりませんが、デバックしようとすると「デバッグ情報がありません」みたいなことを言われるので、デバッグ無しで実行している状態なんです。
とりあえずオブジェクトの処理のほうを見直してみます。
842833:2007/12/30(日) 21:56:44
何度もすいません。
デバッグ情報のほうはなんとかなりましたので、メモリのほうを確認してみます。
843デフォルトの名無しさん:2007/12/30(日) 22:39:39
>>833
とりあえず、環境をプリーズ
844デフォルトの名無しさん:2007/12/30(日) 22:42:44
このスレで扱う程の内容かよ。
845デフォルトの名無しさん:2007/12/31(月) 08:49:10
>>829
なるほろ。それならいけるね。
846デフォルトの名無しさん:2007/12/31(月) 15:00:05
同名の名前空間内で using 宣言の効果の範囲を区切ることは出来ますか?


/* in X.cpp global namespace */

namespace B { namespace C { namespace D { /* 変更不可能 */
struct type_t;
}}}

namespace A { /* 変更可能*/
using ::B::C::D::type_t;
type_t *func( type_t * );
}

namespace A { /* 変更不可能 */
/*
ここに名前 func は導入したいが、名前 type_t は導入したくない。
つまり明示的に ::B::C::D::type_t と指定させたい。
*/
}

/* End of X.cpp */
847846:2007/12/31(月) 15:06:28
ちょっと変更。

namespace B { namespace C { namespace D { namespace {
}}}}

namespace A { namespace {
}}

namespace A { namespace {
}}

です。
848デフォルトの名無しさん:2007/12/31(月) 15:56:18
ファイル分けるとか。
849デフォルトの名無しさん:2007/12/31(月) 16:08:00
本当にそれが必要かを考え直したほうが良いんじゃないか?
850デフォルトの名無しさん:2007/12/31(月) 16:29:28
>>846
これをなくせばいいだけ?
> using ::B::C::D::type_t;
851846:2007/12/31(月) 17:04:21
>>850
実際には、

    namespace A1 { /* 変更可能*/
        using ::B::C::D::type1_t;
        using ::B::C::D::type2_t;
        ……以下略……
        type1_t *func_1( type1_t *, type2_t * );
        type3_t *func_2( type3_t *, type4_t * );
        ……以下略……
    }

    namespace A2 { /* 変更可能*/
        using ::B::E::F::type1_t;
        using ::B::E::F::type2_t;
        ……以下略……

        type1_t *func_1( type1_t *, type2_t * );
        type3_t *func_2( type3_t *, type4_t * );
        ……以下略……
    }

……以下略……

みたいに長めのコードになるので、できれば using 宣言を使いたいのです。
自分は幾つかのサブシステムのうちの一つのサブシステムにある数百のファイルのうちの幾つかを扱っています。
自分の扱っている範囲だけで解決できるような策を探しています。
852デフォルトの名無しさん:2007/12/31(月) 22:59:11
using 使うのはちょっとアイデアが出ないけど

namespace BCD = ::B::C::D;

namespace BEF = ::B::E::F;

みたいな感じでお茶を濁せる気がしないでもないですな
853デフォルトの名無しさん:2008/01/01(火) 00:13:02
新年明けましておめでとうございます。
今年最初の質問をさせていただきます。

ostrstreamをwchar_tで使いたいと思っているのですが、どうしたらいいでしょうか?
要するに、ostrstreamのwchar_t版みたいなクラスがあればいいと思っています。

環境はVC2005、WinXP Proです。
よろしくお願いします。
854デフォルトの名無しさん:2008/01/01(火) 00:19:49
wostrstream

ただし、どのくらい真面目に実装されてるかどうかは知らん。
855デフォルトの名無しさん:2008/01/01(火) 00:43:41
>>851
じゃあusingせずにtypedefで短い名前に
856デフォルトの名無しさん:2008/01/01(火) 00:48:36
>>854
どうもです。それを使ってみます。
857デフォルトの名無しさん:2008/01/01(火) 02:01:41
>>854
すいません、今MSDNを漁ってみたのですが、wostrstream が見つけられませんでした。
もう少し、詳しく教えてください。というか、これでぐぐっても一件しか出てこないのですが……
858 【だん吉】 【1681円】 :2008/01/01(火) 02:08:23
ostringstream
wostringstream
859デフォルトの名無しさん:2008/01/01(火) 02:11:02
wostrstreamくらい自分で作れるだろ……
860デフォルトの名無しさん:2008/01/01(火) 03:04:02
うお。ostrstream の方だったのか。
つーか、そいつは deprecated だから ostringstream 使おうぜ。
861デフォルトの名無しさん:2008/01/01(火) 06:29:49
STLのalgorithmのtransformの使い方で困ってます。以下のソースのコンパイルが通りません。
(実際のソースはdequeコンテナに色々値を挿入する処理とかがあるのですが、省略しました。)

#include <iostream>
#include <deque>
#include <algorithm>
#include <cmath>
using namespace std;
int main()
{
deque<double> radians, sines;
transform(radians.begin(), radians.end(), sines.begin(), sin);
return 0;
}

コンパイルエラーは以下です。
$ g++ transform.cpp -lm
transform.cpp: In function 'int main()':
transform.cpp:9: error: no matching function for call to 'transform(std::_Deque_iterator<double,
double&, double*>, std::_Deque_iterator<double, double&, double*>, std::_Deque_iterator<double,
double&, double*>, <unresolved overloaded function type>)'

でも、sinをsin<int>とするとコンパイルが通るのですが、sin<double>としてもダメです。
sin<int>で問題なく動作するのですが、なぜこう書けば動くのかわからないです。
どうかよろしくお願いします。
環境はg++ 4.2.1でlinuxです。
862デフォルトの名無しさん:2008/01/01(火) 06:53:54
861です。
しかし気がつけばもう2008年か。こんな時間にtransformか、オレ。
863デフォルトの名無しさん:2008/01/01(火) 07:18:27
gccは使ったことがないんだけど、

テンプレート引数をとるsinって何?
complexの奴? それとも使ってるSTLは、C関数によく似たテンプレート版のsinでも提供しているわけ?

VCの場合で答えるけど、VCの標準Cライブラリでは、sin関数が、floatとdoubleを取るように、オーバーロードされている。
それで、曖昧になって、コンパイルできない。
曖昧にならないようにするには。

std::transform( radians.begin(), radians.end(), sines.begin(), static_cast< double (*)(double) >( &sin ) ) ;
864デフォルトの名無しさん:2008/01/01(火) 07:28:01
わざわざキャストするのが面倒だったら、こんな方法もあるけど。

struct SinFuncObj
{
  template < typename T >
  T operator () (T arg)
  { return sin(arg) ; }
} ;


std::transform( radians.begin(), radians.end(), sines.begin(), SinFuncObj() ) ;
865デフォルトの名無しさん:2008/01/01(火) 08:04:56
gcc4.1.2のstdlibc++6のstd::sinはlong doubleとfloatとtemplate関数になってて
std::sin<int>はdouble sin(int)みたいなのとしてインスタンス化されるから通るようだ
でsin<double>だとダメなのはこのtemplate functionの戻り値の定義が
enable_if<double, is_integer<T>::value>::type
のようなのになってて、T=doubleだと(略)::typeによってsin<double>が未定義とみなされ
故に<unresolved overloaded function type>と
しかしtransformのエラーだけ見せられてもなんのこっちゃわからん罠
866デフォルトの名無しさん:2008/01/01(火) 11:06:15
みんなありがとう
865が言っているのは下記の部分についてですか?
自分でも読んでみようと思ったのですが、
__enable_ifがわからん(泣)
googleしても出てきません。

using ::sin;

inline float
sin(float __x)
{ return __builtin_sinf(__x); }

inline long double
sin(long double __x)
{ return __builtin_sinl(__x); }

template<typename _Tp>
inline typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
double>::__type
sin(_Tp __x)
{ return __builtin_sin(__x); }
867デフォルトの名無しさん:2008/01/01(火) 11:51:40
http://www.boost.org/libs/utility/enable_if.html
boostにそっくり。
メタプログラムみたいだね。
想像だけど
__is_integer<_Tp>は_Tpがintegral型だとtrueで、そうでなければfalseになる
として、__gnu_cxx::__enable_if<__is_integer<_Tp>::__value, double>::__type はテンプレートの第一引数型パラメータがfalseに対して
は__typeをtypedefしてない(故意に)からインスタンス化に失敗してエラーと
なってるんじゃないか。trueの場合はdoubleと評価される。

sin<int>だと
__is_integer<int>::__valueがtrue、sin<double>だと__is_integer<double>::__valueがfalse。
868デフォルトの名無しさん:2008/01/01(火) 12:46:50
>>861
アルゴリズムに関数テンプレートを渡すのって
標準に関して言えば違反してるんじゃなかったっけ。
869デフォルトの名無しさん:2008/01/01(火) 12:48:06
sin<int>のように
明示的に型引数与えてコンパイルが通ったとしても。
870デフォルトの名無しさん:2008/01/01(火) 13:24:11
前々から疑問だったんだけど、標準ライブラリとかboostのコードってなんでこう読みにくくしてあるの?
_Tpとか__nとかもうちっと気の利いた変数名をつけようとは思わないんだろうか
それに改行の位置やインデントもバラバラに見えるし
なんか規則があるんだろうけど一般とは全然違うよね
なんでこんなわかりづらいコードなの?
871デフォルトの名無しさん:2008/01/01(火) 13:34:55
Dinkmuwareのソースはわざと読みにくくして、出荷してるんじゃないのかな。
Boostが読みにくいと思ったことはないな。
ソースコードが変態であることには同意するが。
872デフォルトの名無しさん:2008/01/01(火) 13:37:46
生成コードに影響するならともかく、単に読みにくいだけのような気もするし。なんでだろ?
873デフォルトの名無しさん:2008/01/01(火) 13:41:48
標準ライブラリとかboostを使う側のコードと名称が衝突しないようにだろ。
874デフォルトの名無しさん:2008/01/01(火) 13:45:31
名前空間は使えないのかな
875デフォルトの名無しさん:2008/01/01(火) 14:09:11
>>868
kwsk
876デフォルトの名無しさん:2008/01/01(火) 14:29:51
>>873
先頭に _ のついた識別子は処理系やライブラリ用の予約語だから、
衝突するしないだけで言えばそれで _ つけるだけで十分だな。
(本当はもうちょっと複雑なルールなんだけど簡単のため割愛)
877デフォルトの名無しさん:2008/01/01(火) 14:39:24
とすると俺様ライブラリ用の予約語にしてもいいわけだ
878デフォルトの名無しさん:2008/01/01(火) 14:45:21
俺様用は、アンダーバーを3個___にようか。
879デフォルトの名無しさん:2008/01/01(火) 15:18:32
>>876
簡単なら割愛しないで教えてくれよw
880デフォルトの名無しさん:2008/01/01(火) 15:23:10
酔っ払ってんのか?
881デフォルトの名無しさん:2008/01/01(火) 15:32:45
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/jpdndeepc/htm/deep04202000.asp

C90 および C99 規格では、次の名前が実装系のために予約されています。
 * グローバル スコープを持ち、_ で始まる名前
 * _ で始まり、その次が大文字の名前
 * __ で始まる名前
C++ 規格では、次の名前が実装系のために予約されています。
 * グローバル スコープを持ち、_ で始まる名前
 * _ で始まり、その次が大文字の名前
 * __ を含む名前
(C++ の規定の方が予約名の範囲が大きく、2 連のアンダースコア文字が名前の先頭だけでなくどこにあっても予約名になる。)
コードの規格への準拠と移植性を最大限に保つため、自分のプログラムでこのような名前を定義することは避けてください。
この規定を覚えやすくするため、2 連のアンダースコア文字と先頭のアンダースコア文字は言語やスコープに関係なく常に避けるのがよいでしょう。
882デフォルトの名無しさん:2008/01/01(火) 15:41:07
>>875
メイヤーズのSTLの46項に書いてあるけど、
同じ数の型パラメータをとるプライマリテン
プレートのオーバーロード解決ができないみたい。
コンパイラによってはコンパイルできるらしい。
以下はVC++ 2008ではambiguousでエラーだった。

template<typename T>
void func(T t);

template<typename T>
void func(T* t);

int main()
{
int a[] = { 1,2,3 };
for_each(a, a+3, func<int>);
return 0;
}
883デフォルトの名無しさん:2008/01/01(火) 15:47:28
>>875
説明不測だった。以下はVCでもコンパイルできる。
メイヤーズの本では以下も標準では違反してる
らしいと言ってる。とオレは理解した。

template<typename T>
void func(T t);


int main()
{
 int a[] = { 1,2,3 };
 for_each(a, a+3, func<int>);
 return 0;
}
884デフォルトの名無しさん:2008/01/01(火) 15:48:43
ちなみに面倒くさくて標準を調べたことはない。
関数オブジェクト使えばいいから。
885デフォルトの名無しさん:2008/01/01(火) 15:48:52
それはアルゴリズム一般でそうなのか?
それだと greater とか使えんことになるけど。
886デフォルトの名無しさん:2008/01/01(火) 15:59:56
>>885
greaterは関数テンプレートではなくて
クラス(構造体だけど)テンプレートでしょ
887デフォルトの名無しさん:2008/01/01(火) 16:02:24
>>885
お前の使ってるコンパイラのSTLは、greaterをテンプレート関数で実装してんの?
でも、まさかテンプレート関数を渡せないってことは・・・調べるか。
888デフォルトの名無しさん:2008/01/01(火) 16:05:26
>>887
面倒くさがりの皆のために頼む。
889デフォルトの名無しさん:2008/01/01(火) 16:33:15
>>882-883
メイヤーズの本を読んだことがないんだけど、
それは単にArgument Deductionが曖昧になる場合があるって話じゃないの。
テンプレート関数をアルゴリズムに渡すのが規格違反ってことは、
テンプレート関数のポインタが取れないってことになると思うんだけど。
890デフォルトの名無しさん:2008/01/01(火) 16:48:54
>>889
>それは単にArgument Deductionが曖昧になる場合があるって話じゃないの。
そう。メイヤーズの本では、この可能性があるから標準では禁止しているよう
だと書いてある(とオレは理解した)。すまんが原書は読んでいない。
ただ、webで標準のアルゴリズムの章をざっと見たけど何も制限らしいことは
書いていなかった。

実際はどうなんだろ。
891デフォルトの名無しさん:2008/01/01(火) 16:57:51
>>886-887
ああ、クラステンプレートならおkってことか。
892デフォルトの名無しさん:2008/01/01(火) 18:09:05
質問したものだけど、
芋焼酎を飲んで適当にトランプとかやってるうちに、
どんどん高度な(少なくともオレには)書き込みが。。。
みんな今日は1月1日なんだよ、どうしてんだよ
893デフォルトの名無しさん:2008/01/01(火) 18:27:13
お年玉ってやつだ
894 【1850円】 !dama!dama!dama:2008/01/01(火) 18:40:39
orz
895デフォルトの名無しさん:2008/01/02(水) 14:02:10
inlineで質問なんですが、
Foo.hppで定義したclass Fooのインラインメソッドhoge()があった時に
クラスFooのインライン以外の実装をFoo.cppで記述してFoo.oを作成したとします。
この時に、Foo::hoge()を呼び出すclass Barの実装を定義したbar.cppでFoo.hppをインクルードするわけですが、
bar.oを作成するときにFoo::hoge()はインライン展開されるのでしょうか?
ここでFoo::hoge()はトリビアルな関数とします
896デフォルトの名無しさん:2008/01/02(水) 14:05:26
アセンブリコード出してみりゃ分かる
897デフォルトの名無しさん:2008/01/02(水) 16:15:43
>>895
ま、gccやMSVC++ではインライン展開されるよ。ちゃんと。
なにが疑問なんだ。
898デフォルトの名無しさん:2008/01/02(水) 16:19:01
inlineもそうだけどtemplateの実装ってどこのオブジェクトファイルに展開されるんだろ?
899デフォルトの名無しさん:2008/01/02(水) 16:19:20
どういうコードがインラインになるのか、ならないのかは、
ひとえに処理系の裁量に委ねられる。規格には、こういう
コードならインラインせねばならない、というような強行規定は
存在しなかったはず。
900デフォルトの名無しさん:2008/01/02(水) 16:21:45
息を吸うように逆アセンブルすれば万事解決
901デフォルトの名無しさん:2008/01/02(水) 16:22:53
templateとか、class-staticなメンバ関数なんかは、使用した翻訳単位(≒object file)
それぞれで展開され、リンカが、適切に多重存在する実装を纏める、
という処理系がほとんどではないか。
902デフォルトの名無しさん:2008/01/02(水) 16:30:27
>>898
使っているすべてのオブジェクトファイルにコード吐いて、
リンク時に重複を削除とかじゃないのかな。
903デフォルトの名無しさん:2008/01/02(水) 16:40:56
newを使ってメモリ確保するときに、必ず失敗はあると思うのだけど、
C++はその例外処理対策をしてないソースばっかり見かける。

Cのmalloc使った時は、アフォみたいにNULLと比べて
しっかり作ってたんだけど、そこら辺をしてないのはどうしてですか?
904デフォルトの名無しさん:2008/01/02(水) 16:42:40
>>903
そりゃ、実際にはメモリ確保できなかったときに対応する必要はあるんだろうけど。
ほとんど、そんなケースは起こらないから、考えてないだけじゃね?
905デフォルトの名無しさん:2008/01/02(水) 16:45:42
>>903
どこかでcatchしてるからじゃないか?
906デフォルトの名無しさん:2008/01/02(水) 16:46:41
>>903
・例外キャッチだけじゃどうせ片手落ちだから何もしない
・例外キャッチしてもterminateくらいしかすることないから何もしない
のどちらかまたは両方。
907デフォルトの名無しさん:2008/01/02(水) 16:47:40

学生の頃 3次元モデルのシュミレーションやるのに
1000x1000x1000 の double 配列持ったクラスを
new しようとして「実行できない!」ってわめいてた
後輩がいたな…
# おまえそれでも工学部かと(ry
908デフォルトの名無しさん:2008/01/02(水) 16:47:40
まさかnewしてる箇所だけ見て言っているわけではないと思うが。
909デフォルトの名無しさん:2008/01/02(水) 16:48:41
>>903
例外でスコープ飛び出しても、しっかりデストラクタが呼ばれるなど、ある程度コンパイラが自動的に解決してくれてるからとか。
それですまない部分だけ、キャッチするようにしてるんじゃないかな。
910デフォルトの名無しさん:2008/01/02(水) 16:48:53
newが失敗したら再度newだろ常識で考えて
911デフォルトの名無しさん:2008/01/02(水) 16:49:15
例外安全性が考えられていないライブラリを使ってたりすると、自分のところでcatchしてもどうしようもない、というのはある。
912デフォルトの名無しさん:2008/01/02(水) 16:49:31
>>903
まず、
どういうときに例外がスローされると思っているか
例外がスローされなかったら何が保証されていると思っているか

を聞こうか。
913デフォルトの名無しさん:2008/01/02(水) 16:50:03
釣堀だな。
914デフォルトの名無しさん:2008/01/02(水) 16:51:06
>>913
You too!
915デフォルトの名無しさん:2008/01/02(水) 16:53:02
>>903
bad_allocをご存知か?
916デフォルトの名無しさん:2008/01/02(水) 16:59:13
結局、「メモリが足りません」で落ちるか、「NULL触ったよ一般保護違反」で落ちるかの
二択なら、別にどっちでも良いんじゃないの。
そりゃ、メモリが足りないなりにリカバリにつとめるとか
保護違反例外がなくて、NULL触っても動き続ける環境とかなら
話は別だけど。
917デフォルトの名無しさん:2008/01/02(水) 17:00:43
>>916
newがNULLで戻ることは無い(except 馬鹿コンパイラsuch as VC)。

903のOSは何だ?どうすべきかはOSとOSの設定によるだろう。
918デフォルトの名無しさん:2008/01/02(水) 17:01:52
つstd::nothrowというツッコミはお腹いっぱいな。
919916:2008/01/02(水) 17:02:41
>917

そこは、
>Cのmalloc使った時は、アフォみたいにNULLと比べて
>しっかり作ってたんだけど
に対して、別にNULLチェックも要らないといえば要らない、ってはなし。
920デフォルトの名無しさん:2008/01/02(水) 17:05:27
903はどこいったんだよw
921デフォルトの名無しさん:2008/01/02(水) 17:05:28
void*myalloc(size_t size){
if(void *m = malloc(size) ){return m;}
else { perror("memory allocation error"); exit(1);}
}
みたいなコードでお茶を濁すのがよくある話。
922デフォルトの名無しさん:2008/01/02(水) 17:11:10
Cのmallocと違って、C++のnewは、コンストラクタのおかげで確保したメモリ領域に実際に
触ることが多いから、mallocよりは結果のチェックのしがいがあるかもしれんな。
俺はしてないけど。
923デフォルトの名無しさん:2008/01/02(水) 17:15:49
>>907
8GB確保か。32bit OSじゃ無理だが、64bitだったらもうすぐご家庭レベルでも現実的になるかも名w。
メモリ暴落してるし。
924デフォルトの名無しさん:2008/01/02(水) 18:29:11
4KbitのDRAMを並べてたころが懐かしい。
925デフォルトの名無しさん:2008/01/03(木) 09:09:52
コンストラクタ、デストラクタで例外をthrowするな
そして、スマートポインタを使え
926デフォルトの名無しさん:2008/01/03(木) 09:26:10
コンストラクタは投げてもいいじゃん
927デフォルトの名無しさん:2008/01/03(木) 09:39:48
>>926
コンストラクタで、投げると、デストラクタが呼ばれない。中途半端なつくりかけオブジェクトが残される。
928デフォルトの名無しさん:2008/01/03(木) 10:06:29
>>927
初心者にありがちな誤解だね
929デフォルトの名無しさん:2008/01/03(木) 10:12:26
>>927
後始末が必要なことは初期化リストですればいいし
コンストラクタのボディ部分では強い例外保障をすればいいと思う
930デフォルトの名無しさん:2008/01/03(木) 10:22:43
後始末が必要なものはクラスで包んでおけば、どこで例外が起きるとか気にする必要ないんだけどね。

struct A {};
struct B : A
{
std::auto_ptr<int> a, b, c;
B() : a(new int(1)), b(new int(2)), c(new int(3)) {}
};

B* p = new B;

例えばnew int(3)で例外が投げられても、構築済みのメンバa, bと基本クラスAのデストラクタが呼ばれ
Bの為に確保されたメモリも解放される。
931929:2008/01/03(木) 10:33:17
>>930
それを言ったつもりだったけど
端折り過ぎたか

別の話になるけど
auto_ptrをメンバに持つのは、例外指定関連でまずかったような気が
メイヤーズかサッターが言ってたと思う
932デフォルトの名無しさん:2008/01/03(木) 11:08:42
>>930
その場合、a,b,cのデストラクタは呼ばれて、Bのメモリは開放されるのはわかるが、Bのデストラクタは呼ばれるの?
933デフォルトの名無しさん:2008/01/03(木) 11:25:22
>>932
呼ばれないよ。だってBのコンストラクタは完了して無いもん。
934デフォルトの名無しさん:2008/01/03(木) 11:30:19
>>933
すると生成済みのクラスのデストラクタしか呼ばれない。ってことでOK?
生成中のクラスの後始末は、プログラマがするってことかな。
935デフォルトの名無しさん:2008/01/03(木) 11:31:35
>>932
呼ばれないし、呼ばれる必要も無い。
必要なのはスタックの巻き戻しによる
構築済みオブジェクトの解放と
operator delete()によるメモリ解放。
936デフォルトの名無しさん:2008/01/03(木) 11:40:21
つpimplイディオム
937デフォルトの名無しさん:2008/01/03(木) 13:35:01
forのループの途中でbreak;で抜けるのはありですか?
938デフォルトの名無しさん:2008/01/03(木) 13:38:21
ありだろ
939デフォルトの名無しさん:2008/01/03(木) 13:40:14
なし
940デフォルトの名無しさん:2008/01/03(木) 13:41:47
forループ使ったら負けかなと思ってる
941デフォルトの名無しさん:2008/01/03(木) 13:46:37
廻る回数が不定ならwhileを使うべき。
942デフォルトの名無しさん:2008/01/03(木) 13:50:13
再帰で十分
943デフォルトの名無しさん:2008/01/03(木) 13:51:27
俺はbreakが1個ならforを使う。2個以上使う状況では、whileを使ってbreakは使わないようにしている。
944デフォルトの名無しさん:2008/01/03(木) 15:23:23
俺は積極的にSTLのalgorithmを使って自分でループを書かないようにしたいなぁ
945デフォルトの名無しさん:2008/01/03(木) 15:34:48
しかし現状だとforループを使うのも視認性的にある程度仕方ないと思う。
C++0xでrangeやlambdaが入ってきたらalgorithm使いまくりになると思うけど。
946デフォルトの名無しさん:2008/01/03(木) 15:38:30
copy transform for_each あたりは使いまくってるな。
C++0xでlambdaが入ったら、for_eachと組み合わせて
使いまくると思う。あれは凄い便利だから。
947デフォルトの名無しさん:2008/01/03(木) 15:42:58
ほう、0xでlambdaが入ることになったんですか?
948デフォルトの名無しさん:2008/01/03(木) 15:57:04
>>942
否定はしないんだが, c++ って末尾再帰をまともに扱うような
言語仕様になってないじゃん!
g++ あたりだと, 限られた範囲では末尾再帰を繰り返しに
展開するみたいだが…
949デフォルトの名無しさん:2008/01/03(木) 16:02:05
どこのコンパイラがいいですか?
clですか?
g++ですか?

950デフォルトの名無しさん:2008/01/03(木) 16:06:33
icc
951デフォルトの名無しさん:2008/01/03(木) 16:32:33
>>948
モダンなコンパイラなら、末尾再帰ぐらい普通に最適化するだろ。
VCもするし。
952デフォルトの名無しさん:2008/01/03(木) 16:35:37
>>951
相互末尾再帰も最適化してくれる?
953デフォルトの名無しさん:2008/01/03(木) 16:50:05
iccは高いですね。
clのまま、最適化で対応します。
954デフォルトの名無しさん:2008/01/03(木) 16:55:37
移植性、経済性という観点ならばJava環境が良い。
しかし、cygwinがお荷物になる。
955デフォルトの名無しさん:2008/01/03(木) 17:24:10
>>952
C++一辺倒なので相互再帰でしかも末尾再帰なんてコードに価値があることすら知らなかった。
試してみたら、VC9では、無理だった。
でも、C++じゃあまり見ないコードだよね。
956デフォルトの名無しさん:2008/01/03(木) 17:33:28
>>947
現状TR1には入ってないから無理かな。
957デフォルトの名無しさん:2008/01/03(木) 17:39:21
いや、ライブラリとしてのlambdaじゃないだろ。
Boost.Lambdaも面白いけど、とてもアレを実際に使いたいとは思わん。
958デフォルトの名無しさん:2008/01/03(木) 18:46:05
>>955
VC++は相互だとダメだと思うが、普通の末尾再帰の最適化ならやってくれるよ。
/CLRは知らんけど。
959デフォルトの名無しさん:2008/01/03(木) 18:51:11
うーわ、今まで自分で展開してたよorz
960デフォルトの名無しさん:2008/01/03(木) 18:58:38
ええええ!末尾再帰を展開してくれるの?知らなかった。これからは活用させてもらうよ。
961デフォルトの名無しさん:2008/01/03(木) 19:18:28
末尾再起はループにならんよ

VC7.1だけど

int f(x) {
if (x) return f(x - 1) + x;
else return x;
}

_f PROC NEAR
; File c:\tmp\x.c
; Line 3
push ebp
mov ebp, esp
; Line 4
cmp DWORD PTR _x$[ebp], 0
je SHORT $L794
mov eax, DWORD PTR _x$[ebp]
sub eax, 1
push eax
call _f
add esp, 4
add eax, DWORD PTR _x$[ebp]
jmp SHORT $L793
$L794:
; Line 5
mov eax, DWORD PTR _x$[ebp]
$L793:
; Line 6
pop ebp
ret 0
_f ENDP
962デフォルトの名無しさん:2008/01/03(木) 19:20:33
#include <stdio.h>
int add_r(int sum, int i) { if (i<1) return sum; sum += i; return add_r(sum, i-1);}
int add(int i) { int sum = 0; return add_r(sum, i); }
int main(){ printf("%d\n", add(100000)); return 0; }
とりあえず作ってみた。 CL hoge.cpp でコンパイルするとスタックオーバーフロー。
CL /O2 hoge.cppでコンパイルすると結果が出た。
スタックオーバーフローでなにもメッセージが出ないのは何とかならんのでしょうか?
963デフォルトの名無しさん:2008/01/03(木) 19:22:41
>>961
> if (x) return f(x - 1) + x; 
それ + x がスタックに積まれるから末尾になってない
964947:2008/01/03(木) 19:38:50
>>957
言語仕様を変える方のラムダも0xには入らないよ。
965デフォルトの名無しさん:2008/01/03(木) 19:41:48
VC2005で試した。スゲー

int SumZ1(int x,int y)
{
if(x>0)
{
return SumZ1(x-1,y+x);
}
else
{
return y;
}
}

がこうなった。
00401000 mov ecx,dword ptr [esp+4]
00401004 mov eax,dword ptr [esp+8]
00401008 add eax,ecx
0040100A add ecx,0FFFFFFFFh
0040100D test ecx,ecx
0040100F jle SumZ1+1Eh (40101Eh)
00401011 mov dword ptr [esp+8],eax
00401015 mov dword ptr [esp+4],ecx
00401019 jmp SumZ1 (401000h)
966デフォルトの名無しさん:2008/01/03(木) 19:49:02
>>961
static int f_(int x, int a) {
if (x) return f(x-1, x+a);
else return a;
}
int f(int x) { return f_(x,0); }

のように、引数を追加して末尾再帰に変換して実験しないといかんよ。
967デフォルトの名無しさん:2008/01/03(木) 19:49:35
>>966 の二行目のfはf_のtypo.
968デフォルトの名無しさん:2008/01/03(木) 19:53:03
g++だと相互再帰も最適化されるはず。だれか試してみ。
969デフォルトの名無しさん:2008/01/03(木) 19:58:04
>>959
自分で展開って具体的にはどうしていたんだ?
辞令教えて。
970デフォルトの名無しさん:2008/01/03(木) 20:20:38
相互末尾ってこんなのでいい?実用的なのは思いつかない。
bool odd(int i);
bool even(int i) { return (i==0) ? true : odd(i-1); }
bool odd(int i) { return (i==0) ? false : even(i-1); }
971970:2008/01/03(木) 20:23:26
VC++2005/2008 の/O2 で最適化された。 /O1 では×
VC++6は× でした。
972デフォルトの名無しさん:2008/01/03(木) 20:40:59
>>969
末尾再帰はループぶん回すだけだよ
複雑なのになると、ボトムアップとトップダウンで展開して、
ループに置換できないか考える

再帰の除去とかでぐぐるとよろし
973955:2008/01/03(木) 23:57:02
あ、そうか、>>961じゃ末尾再帰にならないか。
もう一度試してみたら、
相互再帰の末尾再帰は、VC9で最適化された。
そもそも、最適化できなかったのが不思議だったんだよね。
MSほどのコンパイラが最適化できないとは思わなかったから。

VC8以前は試すのが面倒。誰かまかせた。
974デフォルトの名無しさん:2008/01/06(日) 18:54:19
    namespace func {
        namespace type {
            typedef type TYPE;
        }

        using namespace type;
        TYPE f( void );
    }



    namespace func {
        typedef type TYPE;
        TYPE f( void );
    }

は何か違いがありますか?
また、長期的に考えて安全そうなのはどちらだと思いますか?
975デフォルトの名無しさん:2008/01/06(日) 19:22:53
TYPE関数がtypeの名前空間内にあるか否か。
どちらがいいかなんてその時の状況による。
976デフォルトの名無しさん:2008/01/06(日) 19:32:10
.hとか.hppとかでusingしたら殺す。
977デフォルトの名無しさん:2008/01/06(日) 19:33:49
前者だと別の名前空間に名前空間 func::type だけを指定して取り込めるな。

namespace type {
typedef type1 TYPE1;
typedef type2 TYPE2; // 新しく型が追加された場合
}

namespace func2 {
using namespace func::type; // <= 前者+using 指令の場合は 自動的に TYPE2 が取り込まれる。

// using func::TYPE1;
// using func::TYPE2; <= 後者+using 宣言だと、この行を追加するまで追加されない。
}
978デフォルトの名無しさん:2008/01/06(日) 19:37:40
>>976
仮に *.h で >>974 の using namespace をしたとして何が問題になる?
979デフォルトの名無しさん:2008/01/06(日) 19:45:00
>>978
hoge.h(仮)をインクルードしたファイル(又はhoge.h自身)のnamespace func内でTYPE型を宣言したときにぶつかる。
980デフォルトの名無しさん:2008/01/06(日) 19:49:57
>>979
>>974 は using namespace しない場合は namespace func に直に TYPE 型を宣言するって言ってるんだから、どっちにしろぶつかると思うが。
981デフォルトの名無しさん:2008/01/06(日) 19:54:29
>>977
974のコードと混ざってるからか意味がわからん。

using namespace func::type; // <= 前者+using 指令の場合は 自動的に TYPE2 が取り込まれる。

何でTYPE2が取り込まれるの?取り込まれるのは、func::type::TYPEでないの?

// using func::TYPE1;
// using func::TYPE2; <= 後者+using 宣言だと、この行を追加するまで追加されない。

名前空間funcにTYPE1やTYPE2は無いと思うんだけど。
982デフォルトの名無しさん:2008/01/06(日) 19:54:53
>>980
namespace func内にTYPE型を宣言する場合は、TYPEは funcの物になる。func内に他の型を宣言する時はfunc内の名称とぶつからないようにするだけ。
typeの持ち物であるTYPEを*.hのnamespace func内でusingするのは問題。

とはいえ、殺すは言い過ぎた。すまんかった。
983デフォルトの名無しさん:2008/01/06(日) 19:55:33
namespace func に TYPE を導入することが目的ならどちらも違いはないと思う。
984デフォルトの名無しさん:2008/01/06(日) 20:03:20
>>977
>名前空間funcにTYPE1やTYPE2は無いと思うんだけど。
説明不足ですまん。TYPE1は旧・TYPEのつもりね。

typedef type2 TYPE2; // 新しく型が追加された場合

namespace func2 {
using namespace func::type; // <= 前者+using 指令の場合は 自動的に TYPE2 が取り込まれる。

using func::TYPE;
using func::TYPE2; <= 後者+using 宣言だと、この行を追加するまで追加されない。
}
985デフォルトの名無しさん:2008/01/06(日) 20:26:42
前者ではtype definitionだけをusingディレクティブ一発で
取り込めるってことね。

986デフォルトの名無しさん:2008/01/07(月) 09:50:17
void hoge( void ){ return static_cast<void>( huga ); }
がコンパイルできるのは正しいことですか?
987デフォルトの名無しさん:2008/01/07(月) 10:09:18
わりとね
988デフォルトの名無しさん:2008/01/07(月) 10:24:20
でも void v = static_cast<void>(hoge); が通らないから使い道ないんだよね。
これが通れば template 書くのが楽そうなんだが。
989デフォルトの名無しさん:2008/01/07(月) 14:48:21
voidは不完全型?
定義できなだろ
990デフォルトの名無しさん:2008/01/07(月) 20:04:58
return 文に直接書く場合は普通に使える。
991デフォルトの名無しさん:2008/01/07(月) 20:10:38
普通に疑問なんだが>>986がコンパイルされたばあい、hugaがスタックに積まれて戻り値として処理されるってことなの?
992デフォルトの名無しさん:2008/01/07(月) 20:17:10
戻り値も無いのに戻り値として処理されるわけがない
993デフォルトの名無しさん:2008/01/07(月) 20:58:59
ほーち
994デフォルトの名無しさん:2008/01/08(火) 04:24:23
>>991
static_cast<void>( huga );
return ;
と書くのと同じ。
995デフォルトの名無しさん
以下のようなテンプレート関数があり、

template<typename X>
typename X::result_type hoge( X x ) { return x(); }

で、result_type が void の場合にコンパイルエラーしないために、
void 型の戻り値は許されてる。