C++相談室 part46

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

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

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

[C/C++ Users Journal]
 http://www.cuj.com/
[cppll (ML)]
 http://www.trickpalace.net/cppll/ (日本語)
6v(^・^)v:2006/01/08(日) 12:18:29
7v(^・^)v:2006/01/08(日) 12:19:06
8v(^・^)v:2006/01/08(日) 12:19:34
9v(^・^)v:2006/01/08(日) 12:22:03
■関連スレ■
【初心者歓迎】C/C++室 Ver.24【環境依存OK】
http://pc8.2ch.net/test/read.cgi/tech/1131691023/
【C++】STL(Standard Template Library)相談室 4
http://pc8.2ch.net/test/read.cgi/tech/1130680264/
C/C++の宿題を片付けます 56代目
http://pc8.2ch.net/test/read.cgi/tech/1135125328/
C/C++でのWindowsPrograming議論スレ(質問お断り)
http://pc8.2ch.net/test/read.cgi/tech/1049790146/
managed C++ やろうぜ!!
http://pc8.2ch.net/test/read.cgi/tech/1014486422/
【.NET】 C++/CLI について語ろうぜ 【最適】
http://pc8.2ch.net/test/read.cgi/tech/1126450441/
ATL/WTL Part4
http://pc8.2ch.net/test/read.cgi/tech/1134388951/
10v(^・^)v:2006/01/08(日) 12:25:16
STLつかうと一気に実行ファイルサイズが10倍に?!

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

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

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

#include <stdafx.h>

後氏ね。

言葉が悪いな。それで教えているつもりか。
まぁヒントぐらいにはなったな。
うむごくろう。

テンプレは以上です。足りない所、間違っている所がありましたら、追加訂正よろ。
11デフォルトの名無しさん:2006/01/08(日) 12:44:58
>>10
1レスで一気にやったら面白みがないだろ。
12デフォルトの名無しさん:2006/01/08(日) 12:46:24
テンプレに面白みなんて求めるなよ
13デフォルトの名無しさん:2006/01/08(日) 12:48:00
>>11
スマソ(´・ω・`)
レスを節約しようとしたんだけど。次回から別レスにするね。
14デフォルトの名無しさん:2006/01/08(日) 12:48:10
何はともあれ乙。

ところでBoostの日本語文書といえばcppllの翻訳を抜かしていいのか?
15デフォルトの名無しさん:2006/01/08(日) 12:49:34
C++相談室 part44
44 http://pc8.2ch.net/test/read.cgi/tech/1128512737/

これ抜けてた。
16デフォルトの名無しさん:2006/01/08(日) 12:51:45
17デフォルトの名無しさん:2006/01/09(月) 05:04:26
メンバ関数ポインタの代入がコメント化した部分でコンパイルエラーがでてしまいます。

class B{
public:
 void func(void){}
 B(void)
 {
  void (B::*p)(void);
//  p=B::func;//エラー メンバー関数は呼び出すかそのアドレスをとらなければならない
 }
};

class C{
 public:
 C(void){
  void (B::*p)(void);
  p=B::func;
 }
};

int main(void){
 B b;
 C c;
 void (B::*p)(void);
 p=B::func;
 return 0;
}

他のクラスやmain関数では上手くいくのに…納得できません
class Bのコンストラクタ内でBのメンバ関数ポインタの代入はできないのでしょうか
18デフォルトの名無しさん:2006/01/09(月) 05:13:26
p = &B::func;
19デフォルトの名無しさん:2006/01/09(月) 05:15:28
>>17
それ、Borlandのコンパイラだろ。多分バグだよ。
gccだとちゃんとエラーが出るぞ。
20デフォルトの名無しさん:2006/01/09(月) 05:23:59
そうです、BCCです

関数ポインタへの代入を全部p = &B::func;にしたらコンパイル通りました。
ありがとうございます。この書き方が正しいのですね。
…ではロベールさんとこの関数ポインタの書き方は、一体???
21デフォルトの名無しさん:2006/01/09(月) 05:38:47
>>20
間違ったサイトを見ずに、規格書を読め。
22デフォルトの名無しさん:2006/01/09(月) 05:46:49
わかりました・・・
23デフォルトの名無しさん:2006/01/09(月) 17:08:34
そのサイト、「メンバ関数ポインタ」でググると一番上に出てくるな
24デフォルトの名無しさん:2006/01/09(月) 17:10:04
悪いsage忘れた
25デフォルトの名無しさん:2006/01/09(月) 17:56:32
間違った知識を流布している時点で、害悪だな。
26デフォルトの名無しさん:2006/01/10(火) 11:09:16
std::cerr の rdbuf をプログラム開始時に
ファイルストリームに変更して、
出力をファイルに落としています。

ofstream ofs("out.txt");
std::cerr.rdbuf(ofs.rdbuf());

場合によってはエラー出力を抑制したいことがあるのですが、
Windows なので /dev/null に出力するということもできません。
ヌルデバイスを表現するストリームというモノは
標準で用意されてるモノなのでしょうか?
27デフォルトの名無しさん:2006/01/10(火) 12:00:37
>>26
/dev/nullがあるから、標準では用意されなかったんだろ。
WindowsはNULにでも出すしかないな。
28デフォルトの名無しさん:2006/01/10(火) 16:10:42
Boost.Iostreams の Null Device とか
29デフォルトの名無しさん:2006/01/10(火) 19:12:27
ちわっす。
相談です。
VC++でやってるんですけどね
ボタンを押したときはちゃんと別ウインドウに表示されるんです。
しかしエンターキーを押したときに用意した別ウインドウに表示されない。
そうとうこまって降ります。
case WM_KEYDOWN:
switch( wParam )
{
case VK_RETURN:
GetWindowText(hWndEdit2,sBuff,79);
SetWindowText(hWndEdit1,sBuff);

return TRUE;
}
return 0;
       case ....以下続く
30デフォルトの名無しさん:2006/01/10(火) 19:15:07
スレ違い。sageろ。死ねばいいのに
31デフォルトの名無しさん:2006/01/10(火) 19:16:19
>>30
なんですれ違いなのか理解不能だが
切々と語ってくれ

sageについては正直すまんかった
32デフォルトの名無しさん:2006/01/10(火) 19:23:20
言語と環境の区別くらい付けてくれ。
33デフォルトの名無しさん:2006/01/10(火) 19:48:54
なんか2chは無条件にsageなきゃいけないと思ってる奴が時々いるな。
技術系の板で質問でageるのは普通だろ。
34デフォルトの名無しさん:2006/01/10(火) 19:51:57
ぶっちゃけPC初心者板でもなきゃageる意味無い。
VBスレが上がっててもVB知らなきゃ答えられんし
35デフォルトの名無しさん:2006/01/10(火) 20:01:57
知ってる奴に見てもらえりゃいいんだから別にいいだろ。
36デフォルトの名無しさん:2006/01/10(火) 20:11:36
iostream の std::endl は、改行文字を出力した後に
バッファをフラッシュしてくれるマニピュレータですが、
この改行文字は固定なのでしょうか?

CR/LF/CR+LF を何らかのフラグで切り替える
ということは出来ないでしょうか?
37デフォルトの名無しさん:2006/01/10(火) 20:14:20
>>33
もうsage強迫観念だよな、精神病の一種だw
なんでそんなになっちゃったんだろう
38デフォルトの名無しさん:2006/01/10(火) 20:36:03
すみません。
坊主憎けりゃ袈裟まで憎い。
スレ違いに腹をたてたばかりに、ageまで憎く思えてしまいました。

ちなみに、>>31
「言語と環境の区別くらい付けてくれ」は、いまいちでした。
「もっと適したスレがある」というべきでした。
反省しています。
39デフォルトの名無しさん:2006/01/10(火) 20:45:12
4036:2006/01/10(火) 20:51:34
やはり ios::binary でオープンして、
'\x0a' を出力するしかないのかなぁ。
4136:2006/01/10(火) 20:59:25
Visual C++ 2005 でしか確認していないのですが、
std::endl は結局のところ "\n" を出力している
だけで、それを受けたストリームが
通常の '\n' の解釈にしたがって改行コードを
出力しているだけですね。
42デフォルトの名無しさん:2006/01/10(火) 21:04:13
WinとかMacって\rだと何が出力されるの?

UNIXだと普通に
\r CR
\n LF
だが
43デフォルトの名無しさん:2006/01/10(火) 21:29:20
自分でマニピュレータ定義した方が早いのでは?
44デフォルトの名無しさん:2006/01/10(火) 21:41:37
昔調べた結果

出力文字 unix dos  mac
\r      \r   \r    \r
\n      \n  \r\n  \r
\r\n    \r\n \r\r\n \r\r

入力文字 unix  dos  mac
\r     \r   \r  \n
\n     \n   \n  \n
\r\n   \r\n  \n  \n\n

45デフォルトの名無しさん:2006/01/10(火) 21:59:33
それって、\r は0x0D で \n は 0x0A?
Perlなんかだと違ったりしているようなので気になった。
ttp://www.din.or.jp/~ohzaki/perl.htm#CRLF_Unify
46デフォルトの名無しさん:2006/01/10(火) 22:00:10
>>44
おおそうなっているのか
Winはdosと変わってないんだよね?
MacもOSXと昔のMacOSで変わってないのかな?
47デフォルトの名無しさん:2006/01/10(火) 22:10:23
>>45
UnixもDOSもMacもASCIIを使っているのでそのとおり。

ついでに言えばストリームをバイナリモードにすればどれもUnixと同じくそのままの文字が出力されるはず。
48デフォルトの名無しさん:2006/01/10(火) 22:55:12
何かのポインタ型をtemplateの型として受け取ったとき、
なんとかtemplate内部で、そのポインタ型の、ポインタじゃないインスタンスを生成する方法ないすかねぇ。

int main(){
Hoge<int*> hoge;
hoge.create();
}

と、した時

template <class TPTR> class Hoge{
TPTR p;
void create(){
//ここで p = new int; としたいのですが……無理っすかねぇ。
}
}

最初からHoge<int>を前提としてtemplate書けって感じですが、そこをなんとか
49デフォルトの名無しさん:2006/01/10(火) 22:56:00
あ、mainが返値なくてすいません
50デフォルトの名無しさん:2006/01/10(火) 23:02:37
>>48
Hogeのテンプレート引数は必ずポインタ型であることが必要なら、
初めから元の型をテンプレート引数に取るようにするのが一番楽。

template <class T> class Hoge{
    T *p;
    void create(){
        p = new T;
    }
};

それが駄目ならboost::remove_pointer<T>

>>49
mainだけはintを返すように宣言してあり、なおかつreturnがなければ
return 0;が行われるという扱いがなされるから問題ない。
51デフォルトの名無しさん:2006/01/10(火) 23:20:25
>>50
レスありがとうございますx2

remove_pointerのソース観てみましたが、いやはやさっぱり分かりません。
もとからない自信が、すっかり無くなってしまいました。

やはりそうですよね…おとなしく書き直すことにします。変更個所オオス!!
52デフォルトの名無しさん:2006/01/10(火) 23:43:40
>>51
boost::remove_pointer<int *>::typeはintになっているという具合。
53デフォルトの名無しさん:2006/01/11(水) 02:12:01
char* func()
{
char *str = new char[100];
char* retstr = str;
delete str;
return retstr;
};

こういう書きかたってマズイんでしょうか。
54デフォルトの名無しさん:2006/01/11(水) 02:18:54
>>53
返したretstrを何に使うの?
55デフォルトの名無しさん:2006/01/11(水) 02:21:35
>>53
ポインタが指すメモリにアクセスするつもりならマズイ。
deleteした時点でもう使えなくなっている。


ところで48が気になったのでremove_pointerを読んでみた。
それで48の望む動作をするコードが一応出来た。

template<typename T> struct remove_pointer
{
};

template<typename T> struct remove_pointer<T*>
{
     typedef T type;
};

template<typename TPTR> struct Hoge
{
     TPTR p;
     void create()
     {
         p = new remove_pointer<TPTR>::type;
     }
};

テンプレートに慣れていないせいなのかなんかキモイ。
やはり普通に元の型でやるべきだと思った。
5653:2006/01/11(水) 02:46:41
よくよく考えてみればマズイですね。
コードに意味はなくなんとなく考えてみただけです。
有難うございました。
57デフォルトの名無しさん:2006/01/11(水) 02:51:18
>>53 そこの delete は delete [] な。
58デフォルトの名無しさん:2006/01/11(水) 06:43:06
>>44
実際にはコンパイラ(のランタイムライブラリ)によって変わるみたいだよ。
だから例えば同じ dos 環境下でも Microsoft のコンパイラで作成したプログラムと
Borland のコンパイラで作成したプログラムでは結果が違う。 >>4 の表のdosの欄は恐らく
Microsoft のコンパイラで作成したプログラムでの結果だろうけど、Borland のコンパイラで
作成したプログラムの場合、"\r\n" の出力結果は "\r\n" のままになる。

cf. http://www.trickpalace.net/cppll/reference/printf.htm ( このページの一番最後 )
59デフォルトの名無しさん:2006/01/11(水) 06:50:53
まあそんなものに依存するプログラムは書くなってことだな
60デフォルトの名無しさん:2006/01/11(水) 12:22:58
>55
typename 付けないといけないです

template<typename TPTR> struct Hoge
{
TPTR p;
void create()
{
p = new typename remove_pointer<TPTR>::type;
}
};
6155:2006/01/11(水) 12:57:20
>>60
おっと、ごめん。
忘れてた。

VCで通ったのでそのまま書いてしまった。
62デフォルトの名無しさん:2006/01/11(水) 19:58:30
前すれにストリームの解説を求めてた人がいたけど、
標準ライブラリの解説は、ここが参考になる。

//www.cc.nao.ac.jp/fsunman/japanese/C++/index.html
63デフォルトの名無しさん:2006/01/11(水) 22:12:42
>>55さん他
うーん、凄い…ありがとうございます。

ここまで簡単に書いて頂いたのに、理解できない自分に絶望ですが。
何故こうなるんだろ…。奥が深いですねぇ(俺には)。
64デフォルトの名無しさん:2006/01/12(木) 21:27:48
こういう怪しげなテンプレートの使い方はModern C++ Designで勉強するしかないな。

テンプレートがもう少し使いやすい概念になってくれるとありがたいんだけどな。
65デフォルトの名無しさん:2006/01/13(金) 01:29:52
Modern C++ Design は序盤のタイプリストまわりが超難解、
template<template<template<hoge>,hoge>,hoge> とかの
多段テンプレートってのはLispの書式に近いんだそうだが、
そのLispの書式がこれまたわけわからんかったりする。
66デフォルトの名無しさん:2006/01/13(金) 01:47:24
要はcarとcdrをtemplateを駆使して実装してる感じか
67デフォルトの名無しさん:2006/01/13(金) 02:04:24
最近はそういう再帰的なテンプレートと並行して,
テンプレートクラスを1つの関数とみなして使う使い方も重要かと.
boost::mpl, boost::type_traits あたりは後者の見方がないと
なかなか使いこなせないように思うのですが.
68デフォルトの名無しさん:2006/01/14(土) 01:44:48
実験データがtab区切りで並んだfileがあって、
10.1 2.33 4.1 8 9.443
とかってあるとする。
こいつの最小桁は小数点何位かを知りたいんだけど、
簡単にやる方法ってあります?
上の数字列を入れると、
0.1 0.01 0.1 1 0.001
と得られると希望通りの動作。
ただし、1.20とかって数字のときにも、
0.1ではなく0.01が出ないと駄目。
69デフォルトの名無しさん:2006/01/14(土) 01:53:38
>>68
実験データひとつを、ひとつの文字列として読み出し、
文字列の後ろから小数点を検索して距離を調べ、
見つかれば距離に応じた値が答え。見つからなければ1。

C++関係無いな。
70デフォルトの名無しさん:2006/01/14(土) 02:00:26
Cなら
scanf("%s.%[^ ]", null, po)
みたいな感じで読めそうだけどC++核のは面倒くさそうだな
71デフォルトの名無しさん:2006/01/14(土) 02:01:18
- C++核
+ C++っぽく書く
7268:2006/01/14(土) 02:57:44
>>69-71
やっぱ、"."を探すしかないよね。
ありがとう。
73デフォルトの名無しさん:2006/01/14(土) 09:54:19
10底のlog取るだけジャン
74デフォルトの名無しさん:2006/01/14(土) 10:25:15
それよりは文字列として'.'を探してやるほうが早そうな気がする。
75デフォルトの名無しさん:2006/01/14(土) 12:08:00
ごめん嘘 速度以前に題意に即さなかった
76デフォルトの名無しさん:2006/01/14(土) 13:26:20
>>73
ただし、1.20とかって数字のときにも、
0.1ではなく0.01が出ないと駄目。

よく嫁
7768:2006/01/14(土) 15:21:06
結局こういうのにした。

double GetPrecision(const string value)
{
int length = value.size();
int dotPos = value.find(".");

if(dotPos>=0) return pow(10., 1+dotPos-length);
else return 1.;
}
78デフォルトの名無しさん:2006/01/14(土) 16:04:26
>>77
const string&にしろよ。
79デフォルトの名無しさん:2006/01/14(土) 16:06:29
ちょっと気になるのが、
dotPosがsigned型であることと、return 1だな。
80デフォルトの名無しさん:2006/01/14(土) 16:26:06
jya, return 2 ni suruyo
81デフォルトの名無しさん:2006/01/14(土) 16:29:24
俺ならintじゃなくて必ずstring::size_typeにするけど、神経質かなぁ?
82デフォルトの名無しさん:2006/01/14(土) 16:33:33
>>77
・引数が値渡しである必要は無いので参照に。
・length は string のメンバ関数を使えばいい。
・find() の引数を長さ1の文字列ではなくひとつの文字に。
・dotPos を fin() の戻り値にあわせて string::size_type に。
・見つからない判定は string::npos で。

double GetPrecision(const string& value)
{
 string::size_type const dotPos = value.find('.');
 if(dotPos != string::npos) return pow(10, 1+dotPos-value.length());
 else return 1;
}
8382:2006/01/14(土) 16:39:17
うは。 pow の引数 signed にキャストしないとえらいことになるな。
84デフォルトの名無しさん:2006/01/14(土) 16:42:00
符号なしは怖いです
for(;i>=0; i--)
8582:2006/01/14(土) 16:45:26
キャストキモス

double GetPrecision(const string& value)
{
 string::size_type const dotPos = value.find('.');
 if(dotPos != string::npos)
  return pow(10,-static_cast<int>((value.length()-1)-dotPos));
 else
  return 1;
}
86デフォルトの名無しさん:2006/01/14(土) 17:46:16
>>82
stringのメンバlengthとsizeは全く同じだよ。好きなほうを選べばいい。
87デフォルトの名無しさん:2006/01/14(土) 19:27:30
>>86 同じだから length = size() という変数での置き換えが不要だということだろう。
88デフォルトの名無しさん:2006/01/14(土) 20:40:18
あるライブラリーのクラスのメンバー変数のメモリ配列がうんこ
なので不都合がおきてる
class Base {
public:
int x_, y_; //ここが問題
//できればこうしたい
// std::vector<int> xy;  int &x_; int &y_;
//Base(int x , int y): xy(2),x_(xy[0]), y_(xy[1]){}

Base(int x , int y): x_(x), y_(y){}
int doSome() { return (x_*y_);}
};
けれど他人のライブラリなので変更できないので
派生クラスで解決しようとした
class Derived :public Base
{
public:
std::vector<int> xy; int &x_; int &y_;
Derived(int x , int y): xy(2),x_(xy[0]), y_(xy[1]){}
};

main()
{
Derived d(1,2)
d.doSome() ;// x_ * y_ = 1*2 が帰ってくるようにしたい。
}
けれどdoSome()はちゃんと動かない当然だけど
Baseを変更しないでメンバー関数doSome()を使う方法ないんでしょうか?
89デフォルトの名無しさん:2006/01/14(土) 20:46:04
>>88
Base b(1,2);
b.doSome();
これで不満な理由がわからんことには答えようが無い。
90デフォルトの名無しさん:2006/01/14(土) 20:54:38
x y がメモリー上で連続に並んでいる場合にしか使えない関数
func(int *p_xy){ return *p_xy + *(++p_xy) }
とかと同時に使いたい
91デフォルトの名無しさん:2006/01/14(土) 20:59:24
>>90
それは Base を使ってる限り無理だな。
ローカルな配列に一旦コピーして、後で戻すことができれば
同じ結果にできるだろうけど。
92デフォルトの名無しさん:2006/01/14(土) 21:01:28
>>90
> func(int *p_xy){ return *p_xy + *(++p_xy) }

これは未定義動作だな。メモリー上の連続性とか関係無しに。
93デフォルトの名無しさん:2006/01/14(土) 21:01:47
>>90
そういう阿呆なことをしようとするな。
94デフォルトの名無しさん:2006/01/14(土) 21:02:20
Derivedでint &x_を宣言したってBaseのメンバ関数からは
Base::x_しかみえんだろうが。
doSomeをオーバーライドしない限りどうしようもなかろうに。
95デフォルトの名無しさん:2006/01/14(土) 21:14:44
>>92
直前の副作用完了点から次の副作用完了点までの間で
同一オブジェクトに対して読み取りや変更が行われる回数は
高々1度でなければならないってのだっけ?よく覚えてないが。
96デフォルトの名無しさん:2006/01/14(土) 21:20:11
>>95
具体的に言ってしまえば*p_xyと*(++p_xy)のどちらが
先に評価されるか未定義になってる。
97デフォルトの名無しさん:2006/01/14(土) 23:41:16
Derived を Baseにcastとか・・・
98デフォルトの名無しさん:2006/01/14(土) 23:53:58
>>97 何この電波?
99デフォルトの名無しさん:2006/01/14(土) 23:58:02
コンストラクタの引数はつかわんのか?
100デフォルトの名無しさん:2006/01/15(日) 04:46:16
お前ら文字エンコードの変換ってどうしてる?
ICU?iconv?std::codecvt?

オレはICUで落ち着きそうなんだが
いい方法、ナイスライブラリがあったら教えて
101デフォルトの名無しさん:2006/01/15(日) 11:13:08
「aiueo 12345」のような入力が各行から入ってくるとき、

std::string s1,s2;
std::cin >> s1 >> s2;

として aiueo を s1 に、12345 を s2 に格納したいのですが、
可能でしょうか?
102デフォルトの名無しさん:2006/01/15(日) 11:26:49
可能です
103デフォルトの名無しさん:2006/01/15(日) 11:44:32
>>102 ありがとうございました。
いままで scanf を使っていたのですが、
C++ のストリームを使う方が安全だし便利ですね。
104デフォルトの名無しさん:2006/01/15(日) 11:54:22
その代わりコストは付くがな。

最近じゃCRTの可変長引数関数にタイプチェックあるんだっけ?
VC8.0限定だった気もするけど。
105デフォルトの名無しさん:2006/01/15(日) 12:14:59
あんなもんサイズ間違えたら終いだ
その前にまず標準に準拠しろと
106デフォルトの名無しさん:2006/01/15(日) 13:30:32
>>104
scanf の方がむしろ書式文字列をパースする
必要があるので、コストつきそうな気もする。
107デフォルトの名無しさん:2006/01/15(日) 13:47:01
>>106
計測せずに言うな
108デフォルトの名無しさん:2006/01/15(日) 14:05:27
>>100
オレも ICU で落ち着いてる。つか、 ICU で良いんじゃね?
他の国際化の機能まで視野に入れると iconv より俄然強力だし
少なくとも std::codecvt よりはマシと思うw
109デフォルトの名無しさん:2006/01/15(日) 15:11:31
>100
使ったことないけど挙げとく。暇ができたら趣味プログラムで使ってみる予定……

ttp://tricklib.com/cxx/ex/babel/

110デフォルトの名無しさん:2006/01/15(日) 16:45:44
すみません、double以上の数字の計算ってどうやってするんですか?
111デフォルトの名無しさん:2006/01/15(日) 16:48:00
>>110
long double
112100:2006/01/15(日) 18:44:37
>>108
iconv は手軽だけど char のみの対応
std::codecvt は使い方がよく判らん + C/C++ 各環境の実装が胡散臭い(wchar_t が 2byteとか)
ICU は大がかりだけど独自UChar に安心感が・・・
その結果で ICU に落ち着きそうな俺ガイル
詳しそうな人の意見が聞けて嬉しいなり

>>109
入れるの忘れてた
それも気になる気になる

レスどーもでした
参考になります、ありがとうございました
113デフォルトの名無しさん:2006/01/15(日) 22:53:54
ICUはなんかサイズが大きいイメージがあっていやん。
そんなに本格的に文字コードを扱う必要がないのなら、codecvtで十分だとは思うけどね。
【C++】STL(Standard Template Library)相談室 4
http://pc8.2ch.net/test/read.cgi/tech/1130680264/622
114デフォルトの名無しさん:2006/01/15(日) 23:08:09
ATLを使うへたれな俺。
115100:2006/01/16(月) 03:10:29
>>113
勉強してみる
ありがとう
116デフォルトの名無しさん:2006/01/16(月) 06:49:32
基底クラスから、
派生クラスのメンバ関数ポインタfuncをだけを元に
メンバ関数を呼び出すことはできませんか?
(this->*func)(param);とするわけにもいかず困っております。

(面倒くさいので、基底クラスでvirtual宣言したくないのです。)

もしくは、イベント処理を実装するのに
よいライブラリ、もしくはヒントでもいいのでありませんか?
boostですか?
117デフォルトの名無しさん:2006/01/16(月) 06:54:50
>面倒くさいので、基底クラスでvirtual宣言したくないのです。

これが根本的に間違っていると思う。
118デフォルトの名無しさん:2006/01/16(月) 10:24:42
X がすでにtypedef されているかを判定する方法ないでしょうか?

disable_if_c< is_class<X>, typedef A'>::type X;

などとすると Xが それ以前にtypedef されていない場合に
Xは定義さfれていません、と怒られます
119デフォルトの名無しさん:2006/01/16(月) 11:19:02
>>116
やりたいことはなんとなく想像尽くけど、別の方法を検討した方がいいと思う。

一番無難なのは、結局基底クラスにexecute関数をvirtualで持って、
派生クラスの内部で状態によって分岐だね。

派生した処理関数の呼び出し方にトリッキーな方法はいくらでもあるけど、
コンパイラの実装依存とかになりやすいし、変に複雑になるんなら
基本に立ち返るのが吉
120デフォルトの名無しさん:2006/01/16(月) 19:08:02
わかりました。
基本に立ち返ります。
121デフォルトの名無しさん:2006/01/16(月) 19:10:23
Boost.Regex が、ICU に対応したからこれから使うなら ICU じゃね?
ただ、Boost や STL のコード中に紛れ込むと違和感は歩けど。
122デフォルトの名無しさん:2006/01/16(月) 19:36:36
>>118 少なくとも標準では、無い。
123デフォルトの名無しさん:2006/01/16(月) 20:50:09
>>116
派生じゃなくてテンプレートを使うのはどうかな?

//base
template class Events<class HandlerT>
{
void event1()
{
Handler::event1();
}
...
};

//derived
class Handler
{
void event1()
{
printf("event1");
}
...
};

Event<Handler> EventHandler;
124デフォルトの名無しさん:2006/01/16(月) 20:51:01
まちがえた
125デフォルトの名無しさん:2006/01/16(月) 23:59:11
>>116
Boost なら Signals とかかな
126デフォルトの名無しさん:2006/01/17(火) 20:52:19
コードの書き方のスタイルについておしえてください
べたに処理を書くのではなく
type2 output1,output2;
DoSome1(type1 &input, type2 &output1);
DoSome2(type2 &output1, type2 &output2);

処理結果outputをclass内のメンバー変数として保持できる
class CDoSome1{
public:
type2 output1;
CDoSome1(type1 &input){output1 = ...}
};
class CDoSome2: public CDoSome1
{
public:
type2 output2;
CDoSome2(type1 &input):CDoSome1(input)
{output2 = ...}
};
というスタイルで処理しています。
けれどやっぱりべた書きのほうがいいのかとも悩んでます。
どちらのほうがいいのでしょうか?
127デフォルトの名無しさん:2006/01/17(火) 21:02:07
>>126
何か間違っている気がしてならない。
128デフォルトの名無しさん:2006/01/17(火) 21:25:05
メンバ関数の中で
delete this;
と自分自身を削除するのはアリなんでしょうか?
129デフォルトの名無しさん:2006/01/17(火) 21:32:27
合法ではある。
130デフォルトの名無しさん:2006/01/17(火) 21:32:50
>>126
そのコードを活かして type2 の替わりに CDoSome1 を使うと、
何らかの結果が格納されていることが保証できる。
それが利点にならないのなら、ほとんど無駄な感じ。
CDoSome2 辺りは、たぶん間違い。

一般的に、クラスが存在する意味を他の人にも
説明できないようなら、クラスを作るべきじゃない。
131デフォルトの名無しさん:2006/01/17(火) 21:34:22
132デフォルトの名無しさん:2006/01/17(火) 21:35:29
>126
最近俺も、戻り値が複数ある関数をクラス化してみたりしてる。
が、コンストラクタで処理を実行するのは如何なものか?
判りにくいから継承もするべきではないと思う。
133デフォルトの名無しさん:2006/01/17(火) 23:29:37
戻り値が複数あるような関数は、
いつもクラス・構造体を返す関数にしている。
134デフォルトの名無しさん:2006/01/17(火) 23:34:56
二つくらいならポインタ渡して代入させてる。
135デフォルトの名無しさん:2006/01/18(水) 03:46:38
関数の後にはすべて throw() などとして
どんな例外を投げるかとかを指定するべきでしょうか?
136デフォルトの名無しさん:2006/01/18(水) 03:53:34
>>135
例外仕様はむしろ避けるべき。
詳しくはC++ Coding Standardsの第75項あたりを参照のこと。
137デフォルトの名無しさん:2006/01/18(水) 04:20:37
ふむ、やっぱ買わなきゃならんか。
32ドルくらいだし買うか、生協で。
その本の内容を読まずにレスするけど、
例外つかわないってのがトレンドなのか?
コンストラクタで例外投げるのは時々躊躇することがあるが。
138デフォルトの名無しさん:2006/01/18(水) 04:22:11
例外を使わないんじゃなくて、例外仕様を使わないのがトレンドなんじゃない?
例外はむしろ使うべきだろ。
コンストラクタでは特に。
デストラクタで投げちゃいかんけど。
139デフォルトの名無しさん:2006/01/18(水) 04:33:06
あ〜そういう意味での「例外仕様」か。納得。
C++ の規格に含まれる例外つー仕様は使うな、
ってことかと思た。

コンストラクタでの例外を投げるのを躊躇するってのは、
投げないって言う意味じゃなくてコンストラクタ内での
投げる場所について慎重になるって意味ね。
中途半端に初期化された状態ってのが怖くて。

ところで、いまさら何をですまんが、
例外でコンストラクタを抜けるときって
そのオブジェクトの *this について
デストラクタ呼ばれるんだっけ?
140デフォルトの名無しさん:2006/01/18(水) 04:34:46
呼ばれないというのを前提で生きてきたんだけど。
141デフォルトの名無しさん:2006/01/18(水) 04:36:43
呼ばれない
142デフォルトの名無しさん:2006/01/18(水) 04:40:00
>>139
> 中途半端に初期化された状態ってのが怖くて。
中途半端に初期化されたオブジェクトが使われることは絶対にないから安心しる。
143デフォルトの名無しさん:2006/01/18(水) 04:48:43
例えばコンストラクタ内で

member1 = new char[100];
if (member1 == NULL) throw std::bad_alloc();
member2 = new char[200];
if (member2 == NULL) throw std::bad_alloc();

とかやるとまずいよなぁ、ってのが
コンストラクタ内での例外に慎重になってた原因の一つ。
144デフォルトの名無しさん:2006/01/18(水) 04:50:06
member1 とか member2 を auto_ptr にして
こわくない、こわくない、って自分に言い聞かせればいいのか?
145デフォルトの名無しさん:2006/01/18(水) 07:34:31
>>143
メンバ変数や派生元クラスのデストラクタは呼ばれる。
動的配列をメンバとして使いたければ std::vector にしとくとか。
146デフォルトの名無しさん:2006/01/18(水) 08:33:19
>>136,138,139
なんか、その「例外仕様」って用語、無茶苦茶紛らわしい命名だね。
いや、仮に、俺がその用語を命名する立場だったとしても同じような名前をつけてしまいそうだとは思うけど。
なんだかなぁ。
147デフォルトの名無しさん:2006/01/18(水) 08:54:49
>>143-144
class Hoge
{
 boost::scoped_array<char> member1;
 boost::scoped_array<char> member2;
public:
 Hoge() : member1(new char[100]), member2(new char[100])
 {}
};

としとけば、member2 の new が std::bad_alloc 投げても member1 の
デストラクタが呼ばれて member1 の char[100] も解放されるね。
148デフォルトの名無しさん:2006/01/18(水) 09:27:10
>>147
とくに効率が問題にならなければ std::vector を
使っておいたほうがいいんじゃないか?

class Hoge
{
 std::vector<char> member1;
 std::vector<char> member2;
public:
 Hoge() : member1(100), member2(100)
 {}
};
149デフォルトの名無しさん:2006/01/18(水) 09:58:16
>>148
今はそういうことを問題にしてるんじゃないんだけど。
150デフォルトの名無しさん:2006/01/18(水) 12:25:20
>>147-149 まぁ、仲良くしとけ。
効率重視なら std::auto_ptr でよくないか?
これでもちゃんと開放されるだろ?
151デフォルトの名無しさん:2006/01/18(水) 12:28:35
>>150
>>147-149のように配列を構築したいときには駄目
auto_ptrが呼び出すのはdeleteだから。
配列の場合delete[]を呼ばないといけないですからね。

# 標準ライブラリにauto_ptrに対応するauto_arrayがないのが惜しまれる
152デフォルトの名無しさん:2006/01/18(水) 12:29:57
auto_ptrを使ってしまうとコピーコンストラクタを書くのが面倒になるんだよな。
153デフォルトの名無しさん:2006/01/18(水) 12:36:31
んじゃ、boost::shared_array だったらおk?
154デフォルトの名無しさん:2006/01/18(水) 12:39:02
おkじゃない?
遅いからって嫌がる人もいるけど。
155デフォルトの名無しさん:2006/01/18(水) 12:39:26
>>147 俺、いままで boost::coped_array でいいところを
boost::shared_array 使って書いていたみたいだ。
156デフォルトの名無しさん:2006/01/18(水) 12:40:00
例外仕様がガラクタ認定なのは面白いよな
Javaかわいそう
157デフォルトの名無しさん:2006/01/18(水) 12:43:11
VC++じゃthrow()しか対応してないしなぁ
158自分用メモ:2006/01/18(水) 12:47:25
159デフォルトの名無しさん:2006/01/18(水) 13:17:03
つまり例外仕様は使うな、でFAってことだな
160デフォルトの名無しさん:2006/01/18(水) 14:27:13
お願いします。
int x;
xに値を代入(0から99)のときに、xが0から9までのときは、
00、01、、、09みたいに頭に0が付くように出力する簡単な方法はないでしょうか。
setwを使うと0が出ません。はじめにケタを調べればできますが、もっといい
方法はないでしょうか。
161デフォルトの名無しさん:2006/01/18(水) 14:29:17
cout << setw(2) << setfill('0') << x << endl;
162デフォルトの名無しさん:2006/01/18(水) 14:32:43
例外仕様は絶対に使わないってルール決めがあれば
throw をマクロで弄って __FILE__ と __LINE__ を例外オブジェクトに付加したり
catch されなくても自分で出した例外を throw の時点で全部ログに吐くなんて使い方もできるしなぁ。

まぁ、C++の規格的には予約語である throw をマクロで弄る時点で違法だけどw
163デフォルトの名無しさん:2006/01/18(水) 14:34:31
>>160
素直に printf 使おうぜ!
printf("%02.2d\n", x);
164デフォルトの名無しさん:2006/01/18(水) 14:35:30
>>163
"%02d"で十分な気が......
165デフォルトの名無しさん:2006/01/18(水) 15:05:33
>>162
予約語をマクロで弄ってはいけないなんて規定あったか?
166デフォルトの名無しさん:2006/01/18(水) 15:28:38
関数ポインタを使ったメッセージディスパッチを作っています。
関数ポインタの型がそれぞれ違う場合、関数ポインタをコンテナのようなものでひとまとめに保持することは不可能でしょうか?

static const int EVENT1 = 0;
static const int EVENT2 = 1;
...
typedef int (*func) (int, int);
func funcArray[SIZE];
funcArray[EVENT1] = func1;
funcArray[EVENT2] = func2;
...
funcArray[EVENT1](10, 10);
と等価なようなことをやろうと思っているんですが、型が違う場合はポインタをバラバラに保持するしかないでしょうか?
167デフォルトの名無しさん:2006/01/18(水) 15:34:32
>>166
仮に型が違う関数ポインタをまとめてコンテナに入れられたとしても、
関数を呼び出すときには、適切な型にキャストしてやらなきゃならないんだから
別々に保持しても変わらないと思うが
168デフォルトの名無しさん:2006/01/18(水) 15:44:12
>>166
「型が違う」ってどの程度違う?
その例だと、(10, 10)で呼び出しているから、
・型はT (T1, T2)という形であり、
・int -> T1, int -> T2の暗黙の変換がある。
という条件を仮定している。
こういう条件があるなら、細かい型の違いを無視して
boost::function<void (int, int)>に入れられたと思う。
169166:2006/01/18(水) 16:02:44
>>167
やっぱり呼び出すときに型情報が要りますよね・・
intにマップしたEVENTXから関数ポインタの型を取得するようなtemplate書こうと思ったけど
結局そのテンプレートにアクセスするときに型が必要で意味なかった orz

>>168
ありがとう。でも引数の数と型から返り値の型まで違うんでboost::functionは無理そうです。
170162:2006/01/18(水) 16:53:52
>>165

バグベアードを作る時に違法じゃないか一応調べてさぁ

>17.4.3.1.1 マクロ名
>1 ヘッダ中でマクロとして定義された名前は,翻訳単位がそのヘッダを取り込んだ場合,いか
>なる用途に対しても,処理系用に予約する。
>2 ヘッダを取り込んだ翻訳単位は,そのヘッダ中で宣言又は定義された名前を定義するマクロを
>含んでいてはならない。更に,そのような翻訳単位は,字句的にキーワードと一致する名前をマ
>クロとして定義してはならない。

てなモノを見つけて、「キーワード(予約語)はマクロで定義するのは違法」って解釈したんだけど、
俺の解釈がなんか間違ってる?

# で、まぁ、違法と認識しつつ結局そのままバグベアードを作ったんだけどw
171デフォルトの名無しさん:2006/01/18(水) 16:59:31
違法て・・・
172デフォルトの名無しさん:2006/01/18(水) 17:07:28
違法等等以前に大混乱の危険
173デフォルトの名無しさん:2006/01/18(水) 17:20:53
>>170
知らなかった。サンクス
174デフォルトの名無しさん:2006/01/18(水) 19:14:31
自作のデータベースから任意の検索条件で検索を行い、
検索結果を一覧で表示するプログラム
をc++builder6で作成するプログラムがわかりません。
どなたか教えてください。
175デフォルトの名無しさん:2006/01/18(水) 19:17:50
そんなものありません
176デフォルトの名無しさん:2006/01/18(水) 19:20:38
>>174
スレ違い

くだすれC++Builder(超初心者用)
http://pc8.2ch.net/test/read.cgi/tech/1117225464/
177デフォルトの名無しさん:2006/01/18(水) 19:32:11
宿題だろこれ、たぶん。
178デフォルトの名無しさん:2006/01/18(水) 20:08:25
>>174
「自作のデータベース」
これ大変な事だぞ。一から作れって言うのか。
BDE使ったらだめなのか。
179デフォルトの名無しさん:2006/01/18(水) 20:09:44
そんな事より、
「プログラムをc++builder6で作成するプログラム」
これ大変な事だぞ。
180デフォルトの名無しさん:2006/01/18(水) 20:12:27
うむ。完成したら俺にもくれ。
181デフォルトの名無しさん:2006/01/18(水) 23:08:47
ちょっと質問
boost::tokenizer::iterator itで(特にコレに限らないけど)
func( *it++, *it );
だと引数の評価順序は不定でしたっけ?
182デフォルトの名無しさん:2006/01/18(水) 23:20:27
>>181 不定。
183デフォルトの名無しさん:2006/01/18(水) 23:24:16
>>151
auto_array など要らない、って禿がゆってた。
ttp://www.research.att.com/~bs/bs_faq2.html#auto_ptr
184デフォルトの名無しさん:2006/01/18(水) 23:28:26
>>182 ありがd
185デフォルトの名無しさん:2006/01/19(木) 13:51:07
//hoge_comp.h-------------------------------------------------------------
struct HogeComp{
int func(){ return 777; }
};
//hoge.h-------------------------------------------------------------
class HogeComp; //hoge_comp.hを伝染させないため、ヘッダではクラス宣言のみ
class Hoge{
HogeComp* hoge_comp; //本当はここは HogeComp hoge_comp; で良いのですが…
public:
Hoge();
~Hoge();
int func_comp();
};
//hoge.cpp-------------------------------------------------------------
#include "hoge.h"
#include "hoge_comp.h" //あえてこの順で
Hoge::Hoge() : hoge_comp( new HogeComp ){}
Hoge::~Hoge(){ delete hoge_comp; }

int Hoge::func_comp(){
return hoge_comp->func();
}
//main.h-------------------------------------------------------------
#include <iostream>
#include "Hoge.h"
int main(){
Hoge hoge;
std::cout << hoge.func_comp() << std::endl;
return 0;
}
hoge.cppでしか使わないhoge_compの宣言と実装とを、hoge.hを読み込む他のソースに伝染させないため
上のように書いています。この書き方はどうなんでしょうか。これではJavaっぽくて、C++の良さを失っていそうな気もします。
186デフォルトの名無しさん:2006/01/19(木) 14:30:29
>>185
Efficient C++だったかに、そういう実装のやり方について書いてあった。
ビルドに要する時間をできるだけ短くするために、そうすることもあると。
187デフォルトの名無しさん:2006/01/19(木) 14:32:38
>>186
良かった、オーソライズして頂き安心しました。
レスありがとうございました。
188デフォルトの名無しさん:2006/01/19(木) 15:56:34
>>185
>hoge.cppでしか使わないhoge_compの宣言と実装
分量にもよるけどhoge_comp.hの内容をhoge.cppに書いて
hoge_comp.hを無しにしてもいいかもね
189uroko:2006/01/19(木) 16:59:25
Modern C++ Design っていう本を読んでいるんですが難しくてよくわかりません。
本の内容に関する質問はこのスレでもよいですか?
190デフォルトの名無しさん:2006/01/19(木) 16:59:59
いいんじゃない?
191uroko:2006/01/19(木) 17:04:46
では、今は仕事中でもあるので後ほど質問を内容を整理して
質問します。よろしくです。
192デフォルトの名無しさん:2006/01/19(木) 17:42:23
unkoかとオモタ
193デフォルトの名無しさん:2006/01/19(木) 17:44:32
unkoかとオモタ
194デフォルトの名無しさん:2006/01/19(木) 17:50:17
質問させてください。
構造体を用意してnewしたあと p_testにポインタで渡しているはずなのに
p_testの中のxとyに未定義の値と表示されそれを他の変数に代入すると
エラーが発生します。

CではエラーにならないのでC++では特別な書き方等あるのでしょうか?
すいませんがご教授お願いします。

typedef struct _POINT{
int x;
int y;
}POINT;
typedef struct _TEST{
int s;
POINT p;
}M_TEST;

int WINAPI WinMain(...){
TEST * test = new TEST;
POINT * p_test = &test->p;
...
195194:2006/01/19(木) 17:52:25
環境を書き忘れました。
VC.net 2003です。先日までVC6.0を使用していました。
196デフォルトの名無しさん:2006/01/19(木) 17:53:29
>>194
たぶんコンパイラ・デバッガの仕業。
未初期化の変数の値を読み込もうとするとエラーにするコンパイラ・デバッガを俺は知っている。
197194:2006/01/19(木) 17:58:28
>>196
返答ありがとうございます。
一応ソースコードには間にZeroMemory関数を使用して初期化しているのですが
結局だめでした。

また関数にポインタも渡せなくて困っています・・・
198196:2006/01/19(木) 17:58:44
>>195
やっぱりそうだ。
VC++ .Net 2003では196のとおり。変数をきちんと初期化すれば良い。
ただの構造体をnewしただけでは初期化されない(0埋めなどされない)
199196:2006/01/19(木) 18:01:13
忘れていた。こうすれば0初期化される。
TEST * test = new TEST();
200デフォルトの名無しさん:2006/01/19(木) 18:06:04
今日からようやくクラスのお勉強に入ります。
201デフォルトの名無しさん:2006/01/19(木) 18:07:11
連絡不要
202194:2006/01/19(木) 18:12:06
>>198
>>199
ありがとうございました。
参考になります。


グローバル変数で
POINT * p_test;
を定義したら中身が見えるようになりました。

お騒がせしました。

あ、というか関数内で定義したポインタは中身見れないのは仕様なのですか?
203デフォルトの名無しさん:2006/01/19(木) 19:10:21
>>202
あなたがやろうとしていることは、C++の流儀には従っていないと思われる。
「こう書けばコンパイルが通るから」という理由で、グローバル変数にするのはやめた方がいい。

void f() {
 TEST* test = new TEST();
}
この場合、TEST型へのポインタtestのスコープは、関数f()内である。
(厳密には、testが宣言された次の文から、関数の最後の}まで)
従って、この関数f()の外からtestにアクセスすることはできない。

複数の関数からtestをアクセスしたければ、次のようなオプションが取れる:
1. アクセスしたいすべての関数にtestへのポインタを渡す
2. 関連のある関数をまとめ、testと共にクラス化する

蛇足だが、ZeroMemory()を使うより、_POINT, _TESTのコンストラクタで初期化した方がいいと思う。
204uroko:2006/01/20(金) 01:03:04
>>189

質問1 (page x)

次のコードは、コンパイル時に評価を行うことができるassertマクロだそうです。

template<bool> struct CTAssert;
template<> struct CTAssert<true> {};

このCTAssertの使い方と、とういう状況のときに使うのかがわかりません。
(コンパイル時に評価をおこなう必要がある状況というのがわからない)
205デフォルトの名無しさん:2006/01/20(金) 01:09:43
>>194
「未定義の値」とはどこに表示されるのか?
他の変数に代入すると発生するエラーの内容(エラーメッセージ)は?
ソース貼るなら実際に動かしてるソース貼れ。
それから、コンパイル通るのぐらい確認しろ。

typedef struct _POINT {...} POINT; は C++ では struct POINT {...}; でいい。
C で使うにしても struct _POINT は struct POINT にしとけ。

>>202
「中身が見える」というのがどういう状態のことを言ってるのかわからん。

>>203
エスパー乙。
test のスコープは厳密には次の文からではなく test の直後から。
206デフォルトの名無しさん:2006/01/20(金) 01:11:27
>>204
ttp://www.kmonos.net/alang/boost/classes/static_assert.html
このあたりが参考になるかと
207uroko:2006/01/20(金) 08:23:47
>>206
ありがとうございます。よくわかりました。
208デフォルトの名無しさん:2006/01/20(金) 15:22:15
プロセスが消費した時間を計測するために使える関数で、
getusage() というものは有るのでしょうか?
昔、どこかのスレッドで同様の質問をしたときに、
getusage() 使え、という回答を頂いたのですが、
getusage() なる関数の使い方を見つけることが
できませんでした。 getusage() という関数は
実在するのでしょうか?
209デフォルトの名無しさん:2006/01/20(金) 15:40:06
>>208
C++標準にはない

これだけだと可哀想なのでフォローしておくと
君が探しているのはたぶん getrusage だろう
210デフォルトの名無しさん:2006/01/20(金) 21:10:56
動的に生成する予定の二次元配列を関数に渡したいのですが,
int* foo( a(*)[ 定数式 ] ) ;
の形式でないと,コンパイラが受け取ってくれない..んですよね?
どうすればいいでしょうか?
できるだけ配列をグローバル変数にはしたくないのですが..
そのほうがオブジェクト指向の適うと思うんです.

<状況>
#include<iostream>
using namespace std ;

int* foo( ) ;

int main( void )
{
int n ; // 配列のサイズ
cin >> n ;

int a[ n ][ n ] ;

・・・ ・・・

int* foo( ) ; // 何とかして配列の先頭アドレスを渡したい

return 0 ;
}

int* foo( )
{
・・・ ・・・
}
211デフォルトの名無しさん:2006/01/20(金) 21:14:42
>>210
> int a[ n ][ n ] ;
これが既にダメ。
212デフォルトの名無しさん:2006/01/20(金) 21:22:19
>>210
いくつかの選択枝がある。
1. std::vector<std::vector<int> >
  ただし、int[][]のようなメモリ上の連続性はないし、大きさの初期化が必要。
2. new
  1.のデメリットに加えて、deleteが面倒くさい。
3. boost::multi_array
  1.2.のデメリットはない。ただし、非標準。
4. その他
213デフォルトの名無しさん:2006/01/20(金) 21:28:52
5.二次元以上の配列を使う奴は馬鹿
214デフォルトの名無しさん:2006/01/20(金) 21:33:53
てんさぁ
215デフォルトの名無しさん:2006/01/20(金) 21:43:32
オブジェクト指向で、グローバル変数なんて使いやがったらしたたかに殴る。
216デフォルトの名無しさん:2006/01/20(金) 21:48:06
↓C(++)に二次元配列はない云々
217デフォルトの名無しさん:2006/01/20(金) 21:58:14
#include<stdlib.h>
int main(){
void * p = malloc(sizeof(int)*100);
((int[10][10])p)[1][2] = 3;
}

Cの話になりそうだけど、こういうことって出来ないの?
218デフォルトの名無しさん:2006/01/20(金) 22:03:56
>>217
それだと結局要素数は定数でなきゃいかんが。
219デフォルトの名無しさん:2006/01/20(金) 22:19:20
(* (int (*) [10][10]) p)[1][2] = 3;

配列のポインタ使えばこんな多分こんな感じ。
220デフォルトの名無しさん:2006/01/20(金) 22:22:41
int[][]が型じゃないから無理
221デフォルトの名無しさん:2006/01/20(金) 22:27:00
なるほど、二次元配列へのポインタにいったんキャストしてから、
デリファレンスするのね。

#include<stdlib.h>
int main(){
typedef int arrint[10][10];
void * p = malloc(sizeof(int)*100);
(*(arrint*)p)[1][2] = 3; //OK
(*(int***)p)[1][2] =3; //error
((int**)p)[1][2] =3; //error
}
222デフォルトの名無しさん:2006/01/20(金) 22:39:22
あ、でもtypedefするときには配列に定数を求められるけど、
使うときにはコンパイラはたとえリテラルが書き込まれてても
チェックしてくれないのね。。。当たり前か。
#include<stdio.h>
#include<stdlib.h>
int main(){
    void * p = malloc(sizeof(int)*100);
    //typedef int arrint[][]; //error
    typedef int arrint[10][10];
    (*(arrint*)p)[0][12] = 3; //OK
    printf("%d\n",(*(arrint*)p)[1][2]);
}
223デフォルトの名無しさん:2006/01/20(金) 23:22:12
>>212
6. std::vector<int>やnew int[n * n]など1次元配列を使う。
薄いラッパでもあれば結構使える。

>>217
たぶんreintepret_cast<int(&)[10][10]>(p)[1][2] = 3;ならいけるはず。

>>221-222
同様にreinterpret_cast<arrint&>(p)[0][12] = 3;や((arrint&)p)[0][12] = 3;とできるはず。
さらにnew arrintというようにはできないか?
しかしtypedefでそもそも要素数がコンパイル時に決定しているので本末転倒。
224デフォルトの名無しさん:2006/01/21(土) 01:17:47
void **Alloc2(size_t x,size_t y,size_t size)
{
 size_t IndexSize=sizeof( void * )*x ;
 void **p=malloc( IndexSize+size*x*y ) ;
 void *pY=( char* )p+IndexSize ;
 size_t i ;
 for( i=0 ; i<x ; i++ ) p[i]=( char* )pY+i*y*size ;
 return p ;
}

int **m ;
m=(int **)Alloc2(n-1,n-1,sizeof(int)) ;

こうやるとコンパイラに怒られます..
void* 型は void** 型に変換できない..と
どうしたものでしょうか?Cでやった時には問題なかったんですが・・
225デフォルトの名無しさん:2006/01/21(土) 01:21:57
void *から任意のポインタ型への変換は、明示的なキャストをする必要がある。

void **p=malloc( IndexSize+size*x*y );

void **p=(void **)malloc( IndexSize+size*x*y ) ;
226デフォルトの名無しさん:2006/01/21(土) 01:22:07
>>224
void **p=(void**)malloc( IndexSize+size*x*y );

次からはどの行でエラーがでたのかちゃんと書こうな?
227デフォルトの名無しさん:2006/01/21(土) 01:28:53
>>223
typedef int arrint[10][10];
arrint * p = new(arrint);

この場合、gcc-3.4.4(cygwin)とVC++7.1の両方で上手くいきませんでした。勘違いしてますかね。
VC++
arrint.cpp(5) : error C2440: 'initializing' : cannot convert from 'int (*)[10]' to 'arrint (*)'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style
g++
arrint.cpp:5: error: cannot convert `int (*)[10]' to `int (*)[10][10]' in initialization

また配列に対する代入および参照のところでgccのだけは挙動がおかしいかったです。VC++では完璧。

(*(arrint*)p)[0][12] = 3; //OK
//((arrint&)p)[0][12] = 3; //gccでは0になる
//reinterpret_cast<arrint&>(p)[1][2] = 3; //gccでは0になる

std::cout << (*(arrint*)p)[1][2] << std::endl; //代入した値を取得できる
//std::cout << ((arrint&)p)[1][2] << std::endl; //なぜか5になる。
//std::cout << reinterpret_cast<arrint&>(p)[1][2] << std::endl; //なぜか5になる。
228デフォルトの名無しさん:2006/01/21(土) 01:33:56
>>225-6

おおーっ!!やっぱりベテランは違いますね!
どうもありがとうございます!m(_._.)m
作ったプログラムが無事にコンパイルできました!
229デフォルトの名無しさん:2006/01/21(土) 02:24:48
>>227
初期化がコンパイル通ってないのに挙動が確認できるのか?
ポインタを参照に reinterpret_cast して挙動がおかしいのは当たり前。
230デフォルトの名無しさん:2006/01/21(土) 02:29:30
>>227
だからboost::multi_arrayを使えと。
231デフォルトの名無しさん:2006/01/21(土) 02:34:57
とりあえず、ソース汚いですけど、これで比べてみてください。

#include<cstdlib>
#include<iostream>
using namespace std;
int main(){
typedef int arrint[10][10];
arrint * p = (arrint *)malloc(sizeof(arrint));
(*(arrint*)p)[0][12] = 12; //OK
((arrint&)p)[0][13] = 13; //OK
reinterpret_cast<arrint&>(p)[0][14] = 14;
cout << "(*(arrint*)p)[1][2] " << (*(arrint*)p)[1][2] << endl;
cout << "(*(arrint*)p)[1][3] " << (*(arrint*)p)[1][3] << endl;
cout << "(*(arrint*)p)[1][4] " << (*(arrint*)p)[1][4] << endl;
cout << "(*(arrint*)p)[0][12] " << (*(arrint*)p)[0][12] << endl;
cout << "(*(arrint*)p)[0][13] " << (*(arrint*)p)[0][13] << endl;
cout << "(*(arrint*)p)[0][14] " << (*(arrint*)p)[0][14] << endl;
232デフォルトの名無しさん:2006/01/21(土) 02:35:46
cout << "((arrint&)p)[1][2] " << ((arrint&)p)[1][2] << endl;
cout << "((arrint&)p)[1][3] " << ((arrint&)p)[1][3] << endl;
cout << "((arrint&)p)[1][4] " << ((arrint&)p)[1][4] << endl;
cout << "((arrint&)p)[0][12] " << ((arrint&)p)[0][12] << endl;
cout << "((arrint&)p)[0][13] " << ((arrint&)p)[0][13] << endl;
cout << "((arrint&)p)[0][14] " << ((arrint&)p)[0][14] << endl;

cout << "reinterpret_cast<arrint&>(p)[1][2] " << reinterpret_cast<arrint&>(p)[1][2] << endl;
cout << "reinterpret_cast<arrint&>(p)[1][3] " << reinterpret_cast<arrint&>(p)[1][3] << endl;
cout << "reinterpret_cast<arrint&>(p)[1][4] " << reinterpret_cast<arrint&>(p)[1][4] << endl;
cout << "reinterpret_cast<arrint&>(p)[0][12] " << reinterpret_cast<arrint&>(p)[0][12] << endl;
cout << "reinterpret_cast<arrint&>(p)[0][13] " << reinterpret_cast<arrint&>(p)[0][13] << endl;
cout << "reinterpret_cast<arrint&>(p)[0][14] " << reinterpret_cast<arrint&>(p)[0][14] << endl;
}
233デフォルトの名無しさん:2006/01/21(土) 02:39:35
>>231
こんなんじゃダメなの?(行数詰めたから見難いけど)
template <typename T> struct array_2d {
    T* data_; int size1_, size2_;
    array_2d(int size1, int size2) : data_(new T[size1 * size2]) , size1_(size1), size2_(size2){}
    ~array_2d() {delete[] data_;}
    struct proxy {
        array_2d* parent_; int offset_;
        proxy(array_2d* parent, int offset) : parent_(parent), offset_(offset) {}
        operator T*() {return parent_->data_ + offset_;}
    };
    proxy operator[](int x) {return proxy(this, size2_ * x);}
};
template <typename T> void assign(T& a) {
    for (int i = 0; i < 2; ++i) for (int j = 0; j < 3; ++j) a[i][j] = 10 * i + j;
}
#include <iostream>
int main() {
    array_2d<int> a(2, 3); assign(a);
    for (int i = 0; i < 6; ++i) std::cout << a.data_[i] << ' ';
    std::cout << std::endl;
    int b[2][3]; assign(b);
    for (int i = 0; i < 6; ++i) std::cout << reinterpret_cast<int*>(b)[i] << ' ';
    std::cout << std::endl;
    return 0;
}
234デフォルトの名無しさん:2006/01/21(土) 02:43:15
>>233
あ、俺は210じゃないっす。ただの通りすがりの暇人ですw

>>229
>ポインタを参照に reinterpret_cast して挙動がおかしいのは当たり前。
あーこれはだめなんですか。未定義の部類になるのかな。じゃあgccとVCで結果が違って当たり前ですね。
235デフォルトの名無しさん:2006/01/21(土) 07:17:46
vtbl内における、各仮想関数ポインタのオフセット位置を得たいのですが、どのように書けばいいのでしょうか?
class X
{
public:
 virtual void func1() {};
 virtual void func2() {};
 virtual void func3() {};
};
のような場合、func1()について0、func2()について4(32ビットシステムの場合)、func3()について8が得られる書き方ですが・・・

あと、インスタンスのVtblのアドレスを得るにはどうしたらよいのでしょうか?
X x;
printf("%X\n", *(void **)&x);
こんな書き方しかないのでしょうか?
236デフォルトの名無しさん:2006/01/21(土) 07:57:42
>>235
処理系依存
確実に取得したいなら自前で仮想関数テーブルをエミュレートするしかない
237デフォルトの名無しさん:2006/01/21(土) 09:02:30
>>235
諦めてメンバへのポインタを普通に使え。
238デフォルトの名無しさん:2006/01/21(土) 14:06:53
>>227
要するに p は配列を指すポインタであるので、
配列を指す参照にキャストしてしまうと、間接参照のレベルが一段ずれてしまう。

配列を指す参照を用いるなら

((int (&) [10][10]) (*p)) [1][2] = 3; が正解
239デフォルトの名無しさん:2006/01/21(土) 20:52:20
キャストを使おうとしている人がほとんどみたいだけど、それって
当然規格はその結果を保証してないよね?
240デフォルトの名無しさん:2006/01/21(土) 23:45:36
えーと、ソースのみにローカルなclassを使うときに、
外部から見えないようにするために、namespace { } を使うのですが、

個人的に.cppにclassを書くので、class内部に実装もがんがん書くし
さらに内部structなんかを持たせる時もある、
なーんて事をしていると、(エディタでソース全体を整形することも多いので)
インデントが深くなってちょっと嫌な感じ。

で、
namespace {
 namespace local {
  class localclass;
 }
}
class local::localclass { ... };
using local::localclass;

などという事を考えたのですが、
これ(無名のnamespaceのさらに内部のスコープだけを明示して使用)って合法ですか?

vc,bcc,gcc等でのコンパイルは問題ないみたいですが。
(未定義のstatic変数のエラーメッセージで確認)
241デフォルトの名無しさん:2006/01/22(日) 00:23:46
>>240
大丈夫だと思います。
242デフォルトの名無しさん:2006/01/22(日) 00:27:58
>240
(質問の意図を思いっきり無視して)
namespaceでインデントしなければいい。
243デフォルトの名無しさん:2006/01/22(日) 00:47:42
ほんとにそれで、大丈夫なんですか?
244デフォルトの名無しさん:2006/01/22(日) 00:51:09
大丈夫だと思います
245デフォルトの名無しさん:2006/01/22(日) 00:54:56
>>241
どもです。

>>242
xyzzyでソース全体を整形すると、勝手にインデントしてしまうのですよ・・・
#includeを使って
"namespace hogehoge {" だけのファイルと
"}" だけのファイルを
先頭と最後に入れてごまかそうとした事も。
246デフォルトの名無しさん:2006/01/22(日) 01:02:58
>>245
> #includeを使って
インデントが深くなるよりもこっちの方が気持ち悪い。
247デフォルトの名無しさん:2006/01/22(日) 01:03:38
狂おしいほどハゲドー
248デフォルトの名無しさん:2006/01/22(日) 01:17:17
>>239
なぜそう思う?

malloc も operator new も 返す型は void* なんですが。
249デフォルトの名無しさん:2006/01/22(日) 01:19:28
>245
ちょっと名前を汚して良いのなら
#define NAMESPACE_hogehoge namespace hogehoge {
#define END_OF_NAMESPACE_hogehoge }
とか?
250デフォルトの名無しさん:2006/01/22(日) 02:00:03
クラスBのオブジェクトをA.cppとC.cpp内で使いたいのですが下記のエラーが出てリンクできません。
どうすればよいでしょうか?

A.OBJ : error LNK2005: "class B b" (?b@@3VB@@A) はすでに C.OBJ で定義されています

(A.h)
#include <stdio.h>
#include "B.h"

extern B b;

class A
{

};

(A.cpp)
#include "A.h"

B b;

int main()
{
return 0;
}
251デフォルトの名無しさん:2006/01/22(日) 02:00:57
(B.h)
class B
{

};

(B.cpp)
#include "B.h"

(C.h)
#include "B.h"

extern B b;

class C
{

};

(C.cpp)
#include "C.h"

B b;
252デフォルトの名無しさん:2006/01/22(日) 02:04:01
a.cpp もしくは c.cpp の B b; をどっちか消せよw
253デフォルトの名無しさん:2006/01/22(日) 02:04:14
>>250
Bのクラス宣言だけをB.hppに残して、定義をB.cppに移動する。
254デフォルトの名無しさん:2006/01/22(日) 02:06:25
汎用的に使いたいってことなら、
a.cpp と c.cpp から B b; を消して b.cpp に書いて、
a.h と c.h から extern B b; を消して b.h に書いとけ。
255デフォルトの名無しさん:2006/01/22(日) 02:12:42
何もかもが間違っている気がする。
256250:2006/01/22(日) 03:17:32
>>252
(B.h)
class B {
public:
int hoge;
};
(C.h)
#include "B.h"
extern B b;
class C {
public:
void func();
};
(A.cpp)
#include "A.h"
//B b;
int main() {
b.hoge;
return 0;
}
(C.cpp)
#include "C.h"
B b;
void C::func() {
b.hoge;
}
これで使い方合ってるでしょうか?
257250:2006/01/22(日) 03:19:03
>>253
(B.h)
class B {
};
(B.cpp)
#include "B.h"
B b;
こうですか?

>>254
error C2146: 構文エラー : ';' が、識別子 'b' の前に必要です。
fatal error C1004: 予期せぬ EOF が検出されました。
コンパイルエラーになりました。
258デフォルトの名無しさん:2006/01/22(日) 03:23:31
#include "stdafx.h"

あと氏ね。
259デフォルトの名無しさん:2006/01/22(日) 03:34:37
パブロフの犬を思い出した
260デフォルトの名無しさん:2006/01/22(日) 03:50:39
>>258
言葉が悪いな。それで教えているつもりか。
まぁヒントにすらなっていないが、
うむごくろう。
261デフォルトの名無しさん:2006/01/22(日) 05:13:09
短気は損気。
気長にマターリ…ねみぃ。。。
262デフォルトの名無しさん:2006/01/22(日) 05:24:47
次期バージョンのC++では、
list<list<int>> l;
と>>の間にスペース入れなくてよくなりそうな感じだね。
263デフォルトの名無しさん:2006/01/22(日) 07:58:00
禿もそうしたいってD&Eに書いてたね
264デフォルトの名無しさん:2006/01/22(日) 08:06:40
>>262 逆になんで今はスペース入れなきゃならないのか、理由がわからない。
265デフォルトの名無しさん:2006/01/22(日) 08:15:54
構文解析上の都合
266デフォルトの名無しさん:2006/01/22(日) 08:23:47
空白が入ってないと、パーサが混乱するんだろうか。
267デフォルトの名無しさん:2006/01/22(日) 08:24:57
レキサは基本的に最長一致だから、構文解析の情報を持たせないと
>>を1つのトークンと見なしちゃう
268デフォルトの名無しさん:2006/01/22(日) 08:33:59
じゃ、古典的な lex & yacc なんかじゃ
パースできないってことか。
現代のコンパイラはレキシカルアナライザが分離してないのが当たり前?
269デフォルトの名無しさん:2006/01/22(日) 09:15:03
質問です
1万桁とかの計算はどうするんですか?
型宣言でlong doubleまでは掛け算割り算できるけどそれ以上の仕方が分かりません
そこら辺も自作しないといけないんですk?
270デフォルトの名無しさん:2006/01/22(日) 09:18:49
多倍長演算
自作するなりそこらに落ちてるライブラリを使うなりご自由に
271デフォルトの名無しさん:2006/01/22(日) 09:21:42
>>270 有名どころっていえばなんでしょうか?
GNU多倍長整数ライブラリですか?
272デフォルトの名無しさん:2006/01/22(日) 09:23:47
って、>>269 は実数演算がしたいみたいだから、
GNU MP ライブラリでいいのか。
273デフォルトの名無しさん:2006/01/22(日) 09:23:58
個人的にはboost::bigintに期待してたり
274デフォルトの名無しさん:2006/01/22(日) 13:33:42
少なくとも g++ と cl.exe は予約語 export をさっさとサポートしる。
話はそれからだ。
275デフォルトの名無しさん:2006/01/22(日) 14:10:23
>>274
exportはサポートしなくても標準に合致している事が保証されたから、
それはなかなか難しいだろう。
276デフォルトの名無しさん:2006/01/22(日) 16:53:40
>>275
それソースプリーズ
277デフォルトの名無しさん:2006/01/22(日) 18:36:00
メンバー関数(func1, func2関数)のポインタをvectorに登録して(Init関数)、
callFunc関数で登録した関数をコールしたいのですが、以下のエラーで
コンパイルできません。コールの方法が間違っていますでしょうか?

Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
func.cpp:
エラー E2314 func.cpp 49: 関数でないものを呼び出している(関数 Func::callFunc(st ::string) )
*** 1 errors in Compile ***

-- ここから --
class Func {
public:
void Init();
int callFunc(std::string);
private:
typedef int (Func::*PFUNC)(std::string);
std::vector<PFUNC> funcs;
int index;
int func1(std::string);
int func2(std::string);
};
278デフォルトの名無しさん:2006/01/22(日) 18:36:37
続きです。

void Func::Init()
{
funcs.push_back(&Func::func1);
funcs.push_back(&Func::func2);
index=0;
}

int Func::func1(std::string str)
{
std::cout << "This is func1: " << str << "\n";
return 1;
}

int Func::func2(std::string str)
{
std::cout << "This is func2: " << str << "\n";
return 2;
}

int Func::callFunc(std::string str)
{
PFUNC pf = funcs[index++];
return (&pf)(str); // ここでエラー
}
279デフォルトの名無しさん:2006/01/22(日) 18:45:50
>>277
メンバ関数のポインタから関数呼び出しをするには、演算子 ->* または .* を使う。

> typedef int (Func::*PFUNC)(std::string);
この typedef ができるのに呼び出し方がわからないってのは、不思議な感じだな。
280デフォルトの名無しさん:2006/01/22(日) 18:56:29
>>279
ありがとうございます。277ですが、C言語は知っているので、
typedefはなんとなくわかっているつもりですが・・・。

>メンバ関数のポインタから関数呼び出しをするには、演算子 ->* または .* を使う。

すみません、具体的にどのように変更すればよいということですしょうか?
return (&pf)(str);を変更するということですよね?

281デフォルトの名無しさん:2006/01/22(日) 19:02:35
282デフォルトの名無しさん:2006/01/22(日) 19:07:26
>>281
すみません、君らと違って暇じゃないもので・・・
283デフォルトの名無しさん:2006/01/22(日) 19:09:07
前方イテレータの方がランダムアクセスイテレータよりスピードやメモリ使用量が優れているとおっしゃるのですか?
284デフォルトの名無しさん:2006/01/22(日) 19:11:35
>>281
コンパイルできますた。
return (this->*pf)(str);
でした。
285デフォルトの名無しさん:2006/01/22(日) 19:27:40
>>283 誰もそんなこと言ってないんじゃないかな。
286デフォルトの名無しさん:2006/01/22(日) 22:40:10
>>282
暇じゃないなら2chに書き込んで都合のいい回答を待つより
自分で調べた方がいいと思う。絶望的に調べ物が下手とかでないなら。
287デフォルトの名無しさん:2006/01/22(日) 22:49:30
>>280
禿本くらい読めアフォ
288デフォルトの名無しさん:2006/01/22(日) 23:06:16
だから禿禿言うなって何回も言ってるだろ!
いい加減起こるぞほんとに
289デフォルトの名無しさん:2006/01/22(日) 23:49:37
何が起こるんだろうか…もしや禿(ry
290デフォルトの名無しさん:2006/01/23(月) 00:10:53
>>287
禿本なんてよまねーよ、カス
291デフォルトの名無しさん:2006/01/23(月) 00:14:03
>>290 そんなこと言うとあなた、禿が起こりますよ。
292デフォルトの名無しさん:2006/01/23(月) 04:21:23
禿の頭舐めたい
293デフォルトの名無しさん:2006/01/23(月) 09:20:54
甘酸っぱいよ
294デフォルトの名無しさん:2006/01/23(月) 09:28:13
プログラミング言語C++:第3版の「7.7関数ポインタ」とかは
四段ですが。別のところに載ってますか?
295デフォルトの名無しさん:2006/01/23(月) 09:56:35
規格書読めや禿げ
296デフォルトの名無しさん:2006/01/23(月) 10:45:51
>>294
15.5
297デフォルトの名無しさん:2006/01/23(月) 11:50:47
>>295
おっしゃる通りです。
読んで来ます。

>>296
禿しくThanXです。
298Stroustrup:2006/01/23(月) 12:00:09
(;`Д´)・・・・・
299デフォルトの名無しさん:2006/01/23(月) 14:27:42
規格、お題目、並べ立てるやつは口先だけの場合が多い
300デフォルトの名無しさん:2006/01/23(月) 17:14:37
>>299
お前も口先だけじゃないか。
301デフォルトの名無しさん:2006/01/23(月) 19:48:36

「禿本読め、コンパイラのマニュアル読め、コード読め。」
これらは相談スレ的には酷すぎんか?

「入門書読め」ならわかるが。

302デフォルトの名無しさん:2006/01/23(月) 19:57:40
>>301
そうだね、あんまり禿、禿、言うのはかわいそう。
303デフォルトの名無しさん:2006/01/23(月) 20:00:59
>>301
禿本は我慢して読むだけの価値があると教えているわけだが?
使い方1つで原価の1万倍くらい当たる本だぞ
304デフォルトの名無しさん:2006/01/23(月) 21:13:35
正直、禿本も読まないでコード書いてるようなヤシとは仕事したくない。
集中して読めば一週間で読了できるのに。理解が進むのはさらに後だとしても。
305デフォルトの名無しさん:2006/01/23(月) 21:25:56
禿本を集中して一週間で読ませるようなヤツもどうかと思うがなw
306デフォルトの名無しさん:2006/01/23(月) 21:26:13
読了しただけで意味あるような禿本なんてあったっけ?
307デフォルトの名無しさん:2006/01/23(月) 21:35:16
>>300
なんだと、おれはちゃんと金もらうだけのことをやってるぞ!
308デフォルトの名無しさん:2006/01/23(月) 21:37:13
>>307
でも、もらってないんだろ? 満額
309デフォルトの名無しさん:2006/01/23(月) 21:40:10
禿本高杉
310デフォルトの名無しさん:2006/01/23(月) 21:46:26
このスレがお笑いスレになっている件について。
311デフォルトの名無しさん:2006/01/23(月) 22:39:51
もったいぶってる奴が多いな
312デフォルトの名無しさん:2006/01/23(月) 23:06:07
C++の本で邦人の著者は柏原正三の一人勝ちなんじゃないかのお。
313デフォルトの名無しさん:2006/01/23(月) 23:16:19
>>312
(゚Д゚)ハァ?
314デフォルトの名無しさん:2006/01/23(月) 23:52:03
>>308
もらってますが何か?
315デフォルトの名無しさん:2006/01/24(火) 00:24:47
なにこのスレ
316デフォルトの名無しさん:2006/01/24(火) 09:26:41
僕の禿本は湿気を吸ってなんだかペラペラになってます
317デフォルトの名無しさん:2006/01/25(水) 08:57:53
2000にspecial editionなんてのが出てるけど、
あれは何か新しいことが書いてあるの?
318デフォルトの名無しさん:2006/01/25(水) 12:42:18
>>317
http://public.research.att.com/~bs/bs_faq.html#SE

ハードカバーになり、その分値段が上がったこと以外の違いはない。
ただし、3rd ed.の初刷からは、記述ミスの修正が1000以上なされている。
319デフォルトの名無しさん:2006/01/25(水) 12:58:51
>>318
残念ながら不正解。直後の、
「As a heavy C++ user, I find that significant. There are also the two new appendices (just over 100 pages; available for download: Locales and Standard-Library Exception Safety).」
を見落としている。まぁダウンロードできるものだが。
320デフォルトの名無しさん:2006/01/25(水) 13:23:24
>>316
俺の禿本は持ちすぎて表紙が溶けかかってる
321デフォルトの名無しさん:2006/01/25(水) 20:04:09
Cだとリスト構造を作るために、構造体に自分と同じ型のポインタの
prevやnextといったメンバを持たせたりするけど、C++の場合は
全てvectorやlistで管理するんですか?
322デフォルトの名無しさん:2006/01/25(水) 20:08:05
>>321
Cスタイルで書きたければCスタイルで書けばいい話じゃ?
323デフォルトの名無しさん:2006/01/25(水) 20:23:33
>>321 まぁそういう便利なクラスライブラリがあるから、
自分でわざわざ作る必要はないけど、
特殊なデータの保持の仕方をしたければ
自分で作ればいいんじゃない?
324デフォルトの名無しさん:2006/01/25(水) 20:28:45
けど基本的にSTLでできることはSTLでするってのが道理だろうな
STLの奴は全部、ある程度以上のパフォーマンスを出せることが
保証されてるわけだし
325デフォルトの名無しさん:2006/01/25(水) 20:29:30
自分で書くメリットがまったくない。
STLを使うと
・素晴らしいアルゴリズムの恩恵を受けられる
・STLは世界共通
・例外安全
・速い
・メモリ領域に関して無駄に悩む必要がなくなる

他にもいろいろあるだろう。
自分で直線的なリスト形式を実装するのは、
Chain Of Responsivilityのときくらい。
326デフォルトの名無しさん:2006/01/25(水) 20:38:44
速いかどうかは微妙だなぁ。
カリカリにチューンするならSTLは使わないけど。
327デフォルトの名無しさん:2006/01/25(水) 20:55:26
STL 多少の非効率はあるよね。
例えばリストなど、新規ノードの追加で必ずコピーコンストラクタが呼ばれる。
ポインタ型にすれば解決できるが、参照とサイズが無駄になる。

328デフォルトの名無しさん:2006/01/25(水) 20:57:52
>>327 もうその辺は気にせず、boost::shared_ptr を食わせたりしてる。
マジでかりかりにチューンが必要な場合は、
スクラッチからコンテナを書くな。

最近コンテナ書いたのって、歯抜けを許すリングバッファかなぁ。
329デフォルトの名無しさん:2006/01/25(水) 21:00:48
STLのスタイルがどうにも合わない
330デフォルトの名無しさん:2006/01/25(水) 21:03:34
>>329
マンコをチンポに合わせるんじゃない。
チンポをマンコに合わせるんだ。
331デフォルトの名無しさん:2006/01/25(水) 23:55:08
ネストしたクラスなんですが

class A
{
private:
 typedef int Hoge;
 static Hoge aaa;
public:
 class B
 {
 public:
  B() { Hoge i = A::aaa; }
 };
};

A::BがAのプライベートメンバにアクセスしても怒られないのですが
これは暗黙に friend class B; が宣言されると解釈していいのでしょうか?
332デフォルトの名無しさん:2006/01/26(木) 00:00:37
>>331
フレンドとは別物。
333デフォルトの名無しさん:2006/01/26(木) 00:08:50
>>331
いや、おかしいと思うぜ
C++ の規格では ill-formed でも診断メッセージの出力は義務づけないとされているケースが多いから
もしかして・・・とは思うが、それは自分で調べれ
334デフォルトの名無しさん:2006/01/26(木) 00:12:06
>>331
BはAのメンバなのだからAのprivateメンバにアクセスできて当然。
class Aの中に書いたものはネストしたクラスでも何でも全てAのメンバ。
335デフォルトの名無しさん:2006/01/26(木) 00:15:41
メンバが static だからだろ
336デフォルトの名無しさん:2006/01/26(木) 00:25:11
C++とフリーのDBでO/Rマッピングできるフリーのライブラリを教えて下さい。
337デフォルトの名無しさん:2006/01/26(木) 00:33:29
>>335
class A
{
private:
 int i;
public:
 class B
 {
 public:
  B()
  {
   A a;
   a.i = 0;
  }
 };
};

なんてのも通りました。コンパイラはVC++2003です。
338デフォルトの名無しさん:2006/01/26(木) 01:08:09
>>337
>A a;
>a.i = 0;
インスタンス化したらコンパイルされるのはあたりまえ。
339デフォルトの名無しさん:2006/01/26(木) 01:28:47
>>331
defect report でアクセスできるように決まった。
そんなわけで古いコンパイラだとアクセスできない。

なんか今 open-std.org が見れないんではっきりソースは出せない。
340デフォルトの名無しさん:2006/01/26(木) 02:13:57
確か、その手の内部クラスへ(から?)のアクセスが
BCC5.5.1とBCC5.6.4で変わってた覚えがあるから(どちらになったかは覚えてないが)
>>339の言う通りに違いないだろう、と俺は思う。
341デフォルトの名無しさん:2006/01/26(木) 02:15:08
あ、もっと古いバージョン(BCB4の奴)かもしれない。
まあとにかく、変わったって事で。
342デフォルトの名無しさん:2006/01/26(木) 08:52:52
343デフォルトの名無しさん:2006/01/27(金) 00:08:50
ちょ、おまえら、あのさ、名前空間を
com::example::cvs::mylib::hoge
とかにするのはどうよ??
344デフォルトの名無しさん:2006/01/27(金) 00:12:36
namespace www::google::com;
345デフォルトの名無しさん:2006/01/27(金) 00:22:24
::の代わりに . が使えたらよかったんだけどな。

>>344 逆じゃね?
346デフォルトの名無しさん:2006/01/27(金) 00:44:53
可変長テンプレート引数って、どうやれば宣言できるの?

tuple<int,int,double,double>
tuple<char,char,int>

みたいなクラスを自分で作りたいんだが。
いろんなところを調べると、

template<class T1,class T2,...,class TM>
class tuple;

みたいな書き方がされてるけど、当然のごとく
このままではコンパイル通らないし…
347デフォルトの名無しさん:2006/01/27(金) 00:48:30
boost::tupleのソースみれ
348デフォルトの名無しさん:2006/01/27(金) 00:51:08
>>346
真に可変長のテンプレート引数なんてものはできない。
デフォルトのクラス指定があって省略可能なだけ。
349デフォルトの名無しさん:2006/01/27(金) 00:58:22
>>348
なるほど。
可能な最大長で宣言されてて、デフォルト引数は無効を示す
型タグになってて、さらに無効な型タグによる特殊化をしてるんだね。
thx
350デフォルトの名無しさん:2006/01/27(金) 01:30:13
>>343-345
名前空間をユニークにするために
標準的に使われている名前付け規則ってある?
351デフォルトの名無しさん:2006/01/27(金) 08:38:09
>>325
C++ を純粋にオブジェクト指向言語としての恩恵を受けるだけのために
使いたいときに、STL や boost を使うともれなくジェネリックプログラミングの
世界に引きずり込まれてしまうのが何かイヤン。
テンプレートは分割コンパイルにも(メジャーなコンパイラは)対応してないし。
352デフォルトの名無しさん:2006/01/27(金) 08:44:32
>>343
なんか Java に影響されすぎだなw

実際問題、名前空間って作者(制作会社)の名前(ニックネーム)や
ソフトの名前が多いと思うけど、適当に付けて被ることそんなにあるかいな。
353デフォルトの名無しさん:2006/01/27(金) 08:48:25
>>352 まぁなぁ、名前空間に関してだけはマジでそう思うんだわ。
というか、インクルードパスと名前空間とを統合した
新しいインポート規則とか便利じゃね?
って、それもJavaに影響され杉とか言われそうだな。
実際、Javaをそれほど使ってる訳じゃないんだが、
どうしてもグローバルにユニークな、ってのに
こだわってしまうんだよな。
それはむしろXMLの名前空間からの影響かも。
354デフォルトの名無しさん:2006/01/27(金) 08:54:36
Java のパッケージの場合は、プログラムをコンパイルしてユーザーがその
プログラムを使うときまでクラスパス指定などでずっとついて回る問題だから、
世界規模でユニークというのを保証するのはまあ必要だと思う。

ただ C++ の場合は、一度コンパイル・リンクしてしまってネイティブコードに
なったら、名前空間もへったくれもないからなあ。
355デフォルトの名無しさん:2006/01/27(金) 09:00:34
だよな

ソースレベルの共有ならリファクタリングブラウザさえあれば問題起きないし
356デフォルトの名無しさん:2006/01/27(金) 09:45:30
>>351
STLのvectorとJavaのArrayListとで、
「ジェネリックプログラミングの世界」とやらの
複雑さは微塵も変わらんと思うんだが。

イテレータだって、その詳細を気にしなければ
ジェネリックプログラミングを意識する必要はないし。

C++ 0xでは、以下のように書けるようになるから
ますますSTLの記法の特殊性は減る。

vector<int> v = { 0, 1, 2, 3, 4 };
for( auto i = v.begin() ; i != v.end() ; ++i ){
  cout << *i << endl;
}
357デフォルトの名無しさん:2006/01/27(金) 10:03:24
c++0x は俺が生きてるうちに出るんかなあ
358デフォルトの名無しさん:2006/01/27(金) 15:32:37
c++0x は俺が生きてるうんち出るんかなあ
359デフォルトの名無しさん:2006/01/27(金) 15:43:00
というよりいつまでC++0xなんて言ってんだ?
今年中に出せマヌケな禿め
360デフォルトの名無しさん:2006/01/27(金) 15:48:50
>>359 まぁそういうなよ。
コーヒーでも飲んで落ち着け。
361デフォルトの名無しさん:2006/01/27(金) 15:57:36
class A
{
A(T a, T b, T c);
T array[3];
};
というクラスで、コンストラクタの初期化でarrayを{a, b, c}に設定したいんですが
どうすればいいんでしょーか。
A::A(T a, T b, T c): array({a, b, c}) {}
A::A(T a, T b, T c): array[0](a), array[1](b), array[2](c) {}
とかやってみましたがエラーが出て終わりですよ!
362デフォルトの名無しさん:2006/01/27(金) 16:00:17
A::A(T a, T b, T c)
{
array[0] = a;
array[1] = b;
array[2] = c;
}
ってやるしかないと思うよ。
363デフォルトの名無しさん:2006/01/27(金) 16:01:48
早!
サンクス!あきらめます!
364デフォルトの名無しさん:2006/01/27(金) 16:27:32
>>361 指定する方法はない(論拠:禿本§10.4.7 クラスの配列)

class Aのコンストラクタの引数に配列を取るようにしたら?
365デフォルトの名無しさん:2006/01/27(金) 17:07:13
>>361
class A
{
  A(T a, T b, T c) : array0(a), array1(b), array2(c) {};
  union {
    T array[3];
    struct {
      T array0;
      T array1;
      T array2;
    };
  };
};
366デフォルトの名無しさん:2006/01/27(金) 17:10:39
無名のunionってアリだっけ?
367デフォルトの名無しさん:2006/01/27(金) 17:14:05
>>365
それってPODにしか使えないからあまり価値なくね?
368デフォルトの名無しさん:2006/01/27(金) 17:25:43
いや、まあどうしても初期化したいのならこうしかないかなぁと。
無名共有体は独自拡張だから使いたくない代物であるのはわかってるけどね。
369デフォルトの名無しさん:2006/01/27(金) 17:31:20
>>368
あれ? Cでは独自拡張だけど、
C++では言語仕様として認められてたはずだけど
370デフォルトの名無しさん:2006/01/27(金) 17:32:47
横からで悪いがマジすか?
規格何ページあたりかわかります?
371デフォルトの名無しさん:2006/01/27(金) 17:33:23
>>369
ゴメ。ぼけてた。
372369:2006/01/27(金) 17:44:25
>>370
規格書持ってないんでPDFの方を見たけど
JIS X3014
130ページの9.5.2 に記述されてた
373デフォルトの名無しさん:2006/01/27(金) 17:47:15
うはwあった。マジでサンクス
C++でも独自拡張かと思ってた
374デフォルトの名無しさん:2006/01/27(金) 18:44:31
ついでにお願いできれば、
struct xxx {
 ...
 char name[0];
};
のような、末尾のメンバのサイズを0に出来るというのも、
Cだと独自拡張でC++だと標準だったような気がするんだけど
どこかに載ってますかね?
375デフォルトの名無しさん:2006/01/27(金) 18:57:43
そんなことが出来たとしてなんか役に立つの??
376デフォルトの名無しさん:2006/01/27(金) 18:59:54
可変長構造体と呼ばれる、かなり有名(かつ邪道)なテクニック
377デフォルトの名無しさん:2006/01/27(金) 19:11:29
ちらっとぐぐったら、
C99では、最後のメンバのサイズを0にするのではなく、
最後のメンバのサイズを省略できるらしいですね。
つまり、事実上ラベルとしてのみ使われるメンバを作れると。
378デフォルトの名無しさん:2006/01/27(金) 20:26:29
VCでSTLのreverse_iteratorが
reference operator[](diff_type Off)
{ return *(*this + Off); }
と実装されてます。
これって一時オブジェクトの参照を返してるように見えるけど
合ってますか?
379デフォルトの名無しさん:2006/01/27(金) 20:31:07
reference の定義を見ないとね、なんとも。
380デフォルトの名無しさん:2006/01/27(金) 20:32:01
質問なんですが、CGIがすでにネットワーク上に用意されていて、
それを実行するためのコマンドもわかっていたら
C++でCGIを呼び出す(?)ことは可能でしょうか?
381デフォルトの名無しさん:2006/01/27(金) 20:32:45
>>378
間違ってる。単に一時オブジェクトのメンバ関数を呼んでいるだけ。
return (*this + Off).operator*();
382デフォルトの名無しさん:2006/01/27(金) 20:44:57
>>380 多分 socket 叩けばできる。
383デフォルトの名無しさん:2006/01/27(金) 20:56:20
>>381
ギャー、operator*(), operator+()を見直したらちゃんとメンバ変数の参照を返してました・・・
どうもありがとうございました。
384デフォルトの名無しさん:2006/01/27(金) 21:35:48
class A
{
private:
void test( void )
{
}
};

template <class T> class B
{
private:
T t;
public:
void testB( void )
{
t.test();
}
};

main()
{
B<A> b;

b.testB();
}

っていうふうにtemplateクラスの関数から別クラスのプライベート関数を呼びたいんですが
どうすればよろしいでしょうか?
templateクラスじゃなければ普通にclass Aにfriend class B;を書けばいいと思うんですが…
おねがいしまつ。
385デフォルトの名無しさん:2006/01/27(金) 21:43:55
>>384
friend class B<A>;
386デフォルトの名無しさん:2006/01/27(金) 21:49:53
template <class T> friend class B;
387384:2006/01/27(金) 21:56:08
>>386
できました。
ありがとうございます。
388デフォルトの名無しさん:2006/01/27(金) 22:13:02
std::listなんですが、sortしてもイテレータが有効なのは保証されているのでしょうか?
あと、どのコンテナがどんな操作をするとイテレータが無効になるか
書いてあるとこありませんでしょうか?
389デフォルトの名無しさん:2006/01/27(金) 22:27:55
内容を破壊しないソートはstable_sort(だっけ?) とかあるからそういうのを使うか、
作業用にコピーして使うとかそんな感じになると思う。
390デフォルトの名無しさん:2006/01/27(金) 22:30:17
>>389
内容を破壊しないソートってなんだよw
391デフォルトの名無しさん:2006/01/27(金) 22:39:02
そもそもstable_sortは、
ランダムアクセスイテレータを条件にしてるからlistに使えねーよw

それに内容を破壊しないんじゃなくてstable_sortは安定したソート。
392デフォルトの名無しさん:2006/01/27(金) 22:41:38
>>388
std::list のイテレータが無効になるのはイテレータが指す要素が削除されたときだけ。

ここ見れば全部分かるよ。
http://www.sgi.com/tech/stl/
393388:2006/01/27(金) 22:46:12
>>392
ウホッ!いいドキュメント。早速ブックマークしました。
ありがとう
394デフォルトの名無しさん:2006/01/27(金) 22:49:07
イテレーターの上書きがないとかそういうのじゃないのか?
395デフォルトの名無しさん:2006/01/27(金) 22:54:38
>>394 何の話だ?
396デフォルトの名無しさん:2006/01/27(金) 23:03:33
stable_sortはマージソート。
並び替える要素の中に等価のものがあっても、
元の順番と変わらない。

quick_sortは安定ではないために、
並び替える要素の中に等価のものがあったら、
元の順番と同じとは限らない。
397デフォルトの名無しさん:2006/01/27(金) 23:30:06
>>396 何の話だ?
398デフォルトの名無しさん:2006/01/27(金) 23:58:09
>>396
stable_sort がマージソートである保証はない.規定されてるのは安定であることと,
追加計算領域を使わない場合 O(n (log n)^2),追加計算領域を使う場合 O(n log n) であることだけ.

これを満たすマージ以外のソートには二分木ソートや,前処理付の不安定ソート群がある.
399デフォルトの名無しさん:2006/01/28(土) 00:28:32
std::list::sort()はstableだったよな確か
400デフォルトの名無しさん:2006/01/28(土) 00:46:17
>>399
yes
401デフォルトの名無しさん:2006/01/28(土) 00:49:31
というより何故listはstableがデフォなんだ
C++的にはlistでも最も高速なやつを標準にして
stableを別個で実装するのが普通だと思うのだが
402デフォルトの名無しさん:2006/01/28(土) 01:10:35
ランダムアクセス出来ないデータ構造で
もっとも速いsortがstableだっていうだけじゃねーの?
403デフォルトの名無しさん:2006/01/28(土) 01:30:24
設計手法のアドバイスをください。

class Ikimono()

class Tako : public Ikimono {
 static int legs;
}
class Neko : public Ikimono {
 static int legs;
}
int Tako::legs = 8;
int Neko::legs = 4;

こんな感じで派生したクラスでクラスに固有の値を設定しています。
聞きたいことは2つで
・上記より何かもっとうまい設計方法はないだろうか
・Ikimonoの派生クラスではlegsの定義を強要させる仕組みはできるか
アドバイスよろしくお願いします。
404デフォルトの名無しさん:2006/01/28(土) 01:34:58
>>403
class Ikimono {
virtual int legs() =0;
};

class Tako : public Ikimono {
  int legs() { return 8; }
};

class Neko : public Ikimono {
  int legs() { return 4; }
};

「うまい設計」かどうかは別として後者は満たしてると思うけど
405デフォルトの名無しさん:2006/01/28(土) 01:47:41
>>404
なるほど。
その手法思いついていたんだけど
Ikimonoをインスタンス化できなくなるのが嫌だなぁと思ってやらなかった。
でもあらためて出されてよく考えるとIkimonoをインスタンス化することなんてねーや。
ありがd
406デフォルトの名無しさん:2006/01/28(土) 01:47:57
>>403
「何かもっとうまい」と言われてもわかんねーよ。
なにが不満なのか言ってもらわないと。
407403:2006/01/28(土) 01:58:02
>>406
いや、マジその通りでごめん。
コンパイル時に具体的なユニークナンバー(4とか8とか)を決定するのではなくて
実行時にダイナミックに設定する方法はないかなぁとぼんやり思って。
(今書いてるプログラムでは>>404で十分なんだけどね)

・実行時にクラス固有の値を設定することができる
・インスタンスを複数生成してもその値は1つでメモリに優しい
・templateを使うとどうなるのかな?

の3つが知りたい方法。
3つ目が馬鹿っぽいこと言ってるのはわかるけどtemplateって個人的に何か憧れるのよw
408デフォルトの名無しさん:2006/01/28(土) 02:04:07
336ですが、
C++にはフリーのO/Rマッピングライブラリは無いんでしょうか?
C++はDB扱うのにはむいてないですか?
409デフォルトの名無しさん:2006/01/28(土) 02:22:45
>>408
言語の向き不向きの問題ではない。自分で作れば?
410デフォルトの名無しさん:2006/01/28(土) 02:26:28
>>407
テンプレートを使ったら「実行時にダイナミックに設定する方法」じゃなくて
「コンパイル時に具体的なユニークナンバーを決定する」ことになるよ。

>>404の方法は、君の要件を完全に満たしている。

無理にテンプレートを使って実現するとすると

struct Ikimono
{
  virtual int legs() = 0;
};

template<int N>
struct IkimonoN : public Ikimono
{
  virtual int lets(){ return N; }
};

typedef IkimonoN<8> Tako;
typedef IkimonoN<4> Neko;
411403:2006/01/28(土) 04:12:17
>>410
なるほど。
ありがd
412デフォルトの名無しさん:2006/01/28(土) 07:39:49
仮想関数のアドレスを得たいのですが、なぜかできません。
単に表示させるのはできるのですが、void型ポインタなどに入れることができません。
どうキャストすればいいのでしょうか?

#include <stdio.h>
class X
{
public:
  virtual func() = 0;
};

class Y : public X
{
public:
  virtual func(){ return 1; };
};

void main()
{
  X *px = new Y;
  printf("%08X\n", &px->func); // これは一応できる
  void *pv = (void *)&px->func; // これはエラー
  int i = (int)&px->func; // これもエラー
}
413ケッミュ:2006/01/28(土) 08:57:26
チミたち、C言語なんて使うのやめなさい。
Visual Studio 2005をつかいなさぁい!
414デフォルトの名無しさん:2006/01/28(土) 09:02:12
Visual Studio 2005 で C 言語使ってますが何か??
415デフォルトの名無しさん:2006/01/28(土) 09:15:37
>>412
メンバ関数へのポインタだろ?
void* や int にキャストって、もしかしてそいつが4バイトとかって前提で考えてるか?
416デフォルトの名無しさん:2006/01/28(土) 09:36:46
>>415がいうように、メンバ関数は4バイト以上になる事がありマス
417デフォルトの名無しさん:2006/01/28(土) 09:38:14
>&px->func
2003だとC2276になるんだけど。
418enumのスコープ(?):2006/01/28(土) 10:02:51
class AAA {
public:
enum BBB {
ITEM1 = 1
};
enum CCC {
ITEM1 = 2
};
};

こうするとエラーになります。
AAA::BBB::ITEM1 と AAA:CCC:ITEM1 は区別される物ではなく、
むしろ両方 AAA::ITEM1 ということでしょうか?
419デフォルトの名無しさん:2006/01/28(土) 10:13:07
>>418
その通り。
420デフォルトの名無しさん:2006/01/28(土) 12:13:37
>>398
(STLの)stable_sortはマージソート
という意味
421デフォルトの名無しさん:2006/01/28(土) 13:29:06
>>420
だから、そのSTLにおいてstable_sortがマージソートでなければいけないって規定はないでしょって話でないの?
422デフォルトの名無しさん:2006/01/28(土) 13:38:41
規格と実装を(ry
423デフォルトの名無しさん:2006/01/28(土) 15:42:22
>>412
標準C++ではできない。
普通はメンバへのポインタを使う。
ただ仮想関数のメンバへのポインタは気が利かせてあって、
きちんとポリモーフィズムが働く。
424デフォルトの名無しさん:2006/01/28(土) 15:50:36
Visual C++で、coutで出てくるコンソール画面をもう一つ表示させて、
エラーを表示させるウィンドウと、処理結果を表示させるウィンドウの二つに分けたいんですけど
そういうことは出来ないでしょうか?
簡単にウィンドウをもう一つ表示っていうのは難しいですかね?
初心者なんですみません。
425デフォルトの名無しさん:2006/01/28(土) 15:54:03
>>424
スレ違い。環境依存OKなスレへどうぞ

【初心者歓迎】C/C++室 Ver.24【環境依存OK】
ttp://pc8.2ch.net/test/read.cgi/tech/1135828083/l50
426デフォルトの名無しさん:2006/01/28(土) 15:54:25
>>424
環境依存なのでスレ違い。
ちなみにWindowsは1プロセス1コンソールと決まっているので
同一プロセス内で2個のコンソールを持つことはできないよ。
427デフォルトの名無しさん:2006/01/28(土) 16:10:08
>>424
std::cout と std::cerr を分ければいいじゃん。
ってところまでは環境非依存。
それぞれのストリームが実際にどこに行くかってのは環境依存。

俺なら std::cerr の rdbuf() に、エラーログ用に開いた
ofstream の rdbuf() をつっこんでエラーログに吐く。
428デフォルトの名無しさん:2006/01/28(土) 16:46:25
C++初心者です。以下のような配列を動的に割り当てるプログラムで、
max の定義がおかしいようなのですが、どう直せばよいのか分かりません。
分かる方、詳しい方、お教えいただければ幸いに存じます。
class stack
{
private:
static int max;//ここがおかしいようです
int data[max];
int sp;
public:
void push(int d){ assert(sp<max); data[sp++] = d;}// データをプッシュ
void pop(){ assert(0<sp); --sp;}// データをポップ
bool empty() const{return sp == 0;}// スタックが空のとき true を返す
int top() const{return data[sp-1];}// スタックトップのデータを返す
int size() const{return sp;}// 現在格納されているデータ数を返す
stack::stack(int sz=100)// コンストラクタ
{
sp = 0;
max = sz;
data = new int[max];
}
stack::~stack() {delete [] data;}// デストラクタ
};
429デフォルトの名無しさん:2006/01/28(土) 16:49:16
>>428
C99ではdata[max]ってのは許容されてるが
C++でもよかったっけ?ダメだったと記憶してるが

素直にvector使え
っていうか、std::stack使え
430デフォルトの名無しさん:2006/01/28(土) 16:50:59
>>428
-static int max;//ここがおかしいようです
+int max;

-int data[max];
+int *data;
431デフォルトの名無しさん:2006/01/28(土) 16:52:02
>>428
宿題はよそでやりなさい。
432デフォルトの名無しさん:2006/01/28(土) 16:59:57
>>428に書き込んだ者です。
>>430さん、ありがとうございました!解決しました。
433デフォルトの名無しさん:2006/01/28(土) 19:14:49
クラス変数とメンバ変数とでは意味が全く異なってるんだが。
問題ないのかねえ。

434デフォルトの名無しさん:2006/01/28(土) 21:57:04
ほんと低レベルなスレだな
435デフォルトの名無しさん:2006/01/28(土) 22:03:47
またお前かw
436デフォルトの名無しさん:2006/01/28(土) 22:34:30
>>434
まぁそりゃ他の高級言語と比べたら低級な言語だからね。
スレも低レベルな話題になるのは仕方がないだろう
437デフォルトの名無しさん:2006/01/28(土) 23:04:39
>>436
メンバ関数へのポインタが void* に変換できない理由について
「低級な」説明ができないアフォがでかい面するところじゃねえよな
438デフォルトの名無しさん:2006/01/28(土) 23:25:02
規格に照らして説明できないやつもでかい面してほしくないな。
4バイトとか、そういうの関係ないだろ。
439デフォルトの名無しさん:2006/01/28(土) 23:32:17
>>437-438
自分ごと批判するってつらくね?
440デフォルトの名無しさん:2006/01/28(土) 23:37:23
自分は批判してないから辛くない
441デフォルトの名無しさん:2006/01/28(土) 23:39:54
どう足掻いても defect なんたらで発言するに至りえないパラダイムを自慢したきゃ
それをやめろと言える場じゃないんで静観するが俺に言わせりゃ(ry
442デフォルトの名無しさん:2006/01/28(土) 23:42:22
間違いを恐れるな
何もしないで文句言ってる
真性のお馬鹿さんよりは1万倍マシ
443デフォルトの名無しさん:2006/01/28(土) 23:48:09
クリリンのことかーーーーっ!!
444デフォルトの名無しさん:2006/01/28(土) 23:54:26
例外、というかtryブロックのパフォーマンスについてです。
try{
hoge();
}
で、hoge()が例外を投げずにreturnできる場合の実行速度は、
tryブロックが無い時と比べて目立って落ちるのでしょうか?

もし囲むだけでも結構なコストがあるのなら、tryの乱発は避けて
ある程度場所を吟味せねばいかんのかな、という事を考えております。
445デフォルトの名無しさん:2006/01/28(土) 23:56:03
>>444
そんなもん自分で計れよ
446デフォルトの名無しさん:2006/01/29(日) 00:02:22
>>445
無理だよ
影響が大きくなりそうなテストパターンと
影響が小さそうなテストパターンが作れない者の
実験と称する無目的な奇行からは何も帰納できないよ
447デフォルトの名無しさん:2006/01/29(日) 00:07:27
448デフォルトの名無しさん:2006/01/29(日) 00:24:01
>>444
try で囲まなくても、デストラクタのあるローカルオブジェクトを作れば
巻き戻しのために try と同等のポイントができる。
ソースコード上に表れる try を避けるだけじゃ意味が無い。
で、ローカルオブジェクトの作成まで吟味してから決めるようだと
ほとんど本末転倒じゃないかな?
449デフォルトの名無しさん:2006/01/29(日) 00:46:07
クラスについて質問なのですが
class AAA {
private:
int a[10];
}
のようなクラスがあったとして A  aaa;と宣言します。
ここからaaaのポインタを取得してprivateで宣言されてる変数にアクセス
することは可能ですか?
450デフォルトの名無しさん:2006/01/29(日) 00:46:47
まぁ可能
451デフォルトの名無しさん:2006/01/29(日) 01:15:12
>>449 不可能。
452デフォルトの名無しさん:2006/01/29(日) 01:19:36
>>449
#define private public
とすればいいやん。
453デフォルトの名無しさん:2006/01/29(日) 01:22:09
>A  aaa;

undeclared identifier 'A'.
454デフォルトの名無しさん:2006/01/29(日) 01:26:31
>>449
改めて言っておく。鼻から悪魔が(ry
#include <iostream>
class dummy {public:int a[10];};
class AAA {
public:
    AAA(){for (int i = 0; i < 10; ++i) a[i] = i;}
private:
    int a[10];
};
int main(void) {
    AAA a;
    int *pa = reinterpret_cast<dummy*>(&a)->a;
    for (int i = 0; i < 10; ++i) std::cout << pa[i] << ' ';
    std::cout << std::endl;
}
455デフォルトの名無しさん:2006/01/29(日) 01:32:44
万策尽くせば可能かもしれないけど
そんなこと自体考えてはいけない
456デフォルトの名無しさん:2006/01/29(日) 01:36:58
boostで>>452を見た気が
457デフォルトの名無しさん:2006/01/29(日) 02:11:46
スタイルの問題と言うか、設計の問題と言うか、
前々からどうすべきなのか悩んでいることがあるので
皆さんならどうするのか質問させてください。

class A でコンストラクタで設定するパラメータとして、
多くの場合にはデフォルト値を使用するため、次のようにします。

class A
{
public:
  static const int default_a;
  A(int a = default_a) : a_(a) {}
private:
  int a_;
};

他のクラスBやCでも同じようにします。
すると、このdefault_aとかdefault_bとかはほとんど変更しないため、
結果的にあちこちのクラスに定数が散らばってしまうことになります。
これの何が問題なのかというと、
結局クラスを利用する側ではほとんどデフォルト値だけを使用して、
たまにプログラム全体の挙動を変更させたい場合にだけ、
default_aとかの値自体を変更してコンパイルし直して
テストしたりするわけです。
その場合に、あちこちのファイルに回って、
default_hogeを変更するのが面倒だなあ、と。
458457:2006/01/29(日) 02:12:52
続き

AやBやCを利用する側のクラスとかでまとめて定数を定義すれば
いいのかもしれませんが、
利用者側がクラスの定数を定義しているというのは変な気がします。
A,B,Cで共通のヘッダファイルを読み込ませるしかないのかもしれませんが、
このaとかbとかは、それぞれのクラス固有の情報なので、
別のところに定数が設定されてるのもなんだかなあ、という気がしますし、
A,B,Cとか、全く関連のないもの同同士の情報が一箇所に集まってるのも
どうかな、という気がします。
クラスの独立性を重視した場合、
A固有の情報である定数が、他の定数を定義してある部分と
同時に与えられるのはどうも気持ちが悪いというか。

A,B,C、みたいな書き方だと、なんかこいつら仲間みたいだから
一箇所で定義すればいいだろ、みたいに思えますが、
全く関連のないもの同士だと考えてください。

デフォルト値を一切しないで、利用する側で、適宜、
利用者側の定数(利用する側では、常にこの値を用いる)、
みたいなものを作る方法も考えましたが、
クラスA等を、複数の場面で利用する場合を考えると、
デフォルト値はあった方が便利な気がします。

すごく長くてすいません。
459デフォルトの名無しさん:2006/01/29(日) 02:17:24
外部から取り込む仕様にすれば良いのでは?
460デフォルトの名無しさん:2006/01/29(日) 02:17:52
>>457-458
難しい日本語でよくわからないが、たぶんそれはお前の都合でしか決められない。
461デフォルトの名無しさん:2006/01/29(日) 02:19:22
>>458 俺もよく悩む。
結局ちらばってしまうか、
共通ヘッダで何とかするか、
しかおもいつかない。
462デフォルトの名無しさん:2006/01/29(日) 02:26:37
もう一案

class A
{
public:
  A(int a = ::createDefault_a()) : a_(a) {}
private:
  int a_;
};

で、クライアント側で、必ず「::createDefault_a()」を実装させる
463デフォルトの名無しさん:2006/01/29(日) 02:27:33
>>462
それがどうした
464デフォルトの名無しさん:2006/01/29(日) 02:38:07
この有り難さが解らんのか・・・
>>457の悩みは解決してると思うが
465デフォルトの名無しさん:2006/01/29(日) 02:42:41
共通ヘッダでいいよ。
ちゃんとnamespace使ってれば。
466457:2006/01/29(日) 02:43:30
>>459-465
皆さんありがとうございます。

>>460
確かに自分でも、なんか無茶なことを言ってる気がしてきました。
自分がそのクラスをどう作りたいのか、によりますね。

>>462
それだと、AからZまでクラスがあったら、
クライアント側で26個関数を供給する必要があって
デフォルトどころか、逆に大変な気がします。

やっぱりうまい方法はないというか、無理な要求っぽいですね。
今後も悩み続けることにします…
467デフォルトの名無しさん:2006/01/29(日) 02:48:07
>それだと、AからZまでクラスがあったら、
>クライアント側で26個関数を供給する必要があって
>デフォルトどころか、逆に大変な気がします。
・・・・・
そう言うもんな気がする

>クラスA等を、複数の場面で利用する場合を考えると、
これがしたいのなら尚更
468デフォルトの名無しさん:2006/01/29(日) 02:59:37
クライアント側に負荷掛けさせたくないのなら

class ZENBU {
  sratic int reateDefault_a() {
    return 1;
  }
}

template<class T=ZENBU>
class A
{
public:
  A(int a = T::createDefault_a()) : a_(a) {}
private:
  int a_;
};
469457:2006/01/29(日) 03:22:42
>>467
確かに、>>457-458で言ってたことは、
設計上のトレードオフで相反する要求を
同時に克服しようとしている感じで、
要求自体が矛盾してるという感じですね。

>>468
利用される異なる場面で、それぞれ異なるデフォルト値を与えることができ、
そのデフォルト値を用いて引数なしのコンストラクタが呼び出せる
ということで、利点はあると思いますが、
もう一段階メタなデフォルトの概念ができるというか、
結局 class ZENBU は共通ヘッダファイルと同じことのような気がします。

>>457-458
は、はじめはデフォルト値は変更しないものとして
利用されることを想定して設計したものが、
その後、変更したくなってしまったために面倒なことになった、ってことで、
設計がおかしい、って結論な気がします。
470デフォルトの名無しさん:2006/01/29(日) 03:31:16
>結局 class ZENBU は共通ヘッダファイルと同じことのような気がします。
同じなのは確か
>もう一段階メタな
それが狙い
唯、メソッドにしておくと、後々便利
プロパティファイルから取り込む変更とが楽

それから設計は、おかしくないと思う
実務っぽいAPLになってしまうけど
471デフォルトの名無しさん:2006/01/29(日) 03:33:58
>>468のメリットはクライアントが拡張したいときは
class NANIKA : ZENBU{
  static int createDefault_a(){//これ以外は標準のまま
   return 2;
  }
};
みたいに拡張したい部分だけかけることだな。
まぁ殆ど書き換えるときは大して変わらないけど。
472デフォルトの名無しさん:2006/01/29(日) 06:06:29
>457
単純に引数デフォルト値の悪用じゃね?
デフォルト値を設定しなければ済む話じゃないの。
473デフォルトの名無しさん:2006/01/29(日) 11:59:01
まぁ>>457が決めなさいってところか?
俺ならconfig.h作って#includeだけどコンパイルが糞重くなるよなぁ
474デフォルトの名無しさん:2006/01/29(日) 12:07:17
>>473 config.h は autoconf がつかうからイヤン
475デフォルトの名無しさん:2006/01/29(日) 12:22:07
autoconf自体がイヤン
476デフォルトの名無しさん:2006/01/30(月) 00:45:00
vector型の変数eを先頭のデータから順に表示するにはどうすればいいですか?
477デフォルトの名無しさん:2006/01/30(月) 00:49:52
>>476
一つのデータを表示する方法と、データを順に取り出す方法を組み合わせるといいよ。
478デフォルトの名無しさん:2006/01/30(月) 00:54:47
>>476
copy + ostream_iterator
# 正直このくらいなら直にループ書いたほうが楽な気もするけどなー
479デフォルトの名無しさん:2006/01/30(月) 01:10:19
>>476
1. ループを書く
2. for_each()にファンクタを渡す
3. boost::lambdaを使う
4. C++/CLIでfor each構文を使う

C++では無名関数が使えないので、
どれもぱっとしないのだが
480デフォルトの名無しさん:2006/01/30(月) 01:15:18
>>477>>478ありがとうございました
481デフォルトの名無しさん:2006/01/30(月) 07:50:44
std::copy( e.begin(), e.end(), std::ostream_iterator<int>(std::cout,"\n") );
482デフォルトの名無しさん:2006/01/30(月) 07:52:13
C++にはなんでevalがないの?
483デフォルトの名無しさん:2006/01/30(月) 08:16:20
>>482
欲しかったら自分で実装してね。
実行ファイルがいちいちインタプリタぶらさげる羽目になるけど。
そうでなくても共有ライブラリをうまく使えばましにはなるかもしれないね。
そうすると結局C++でなく他のインタプリタ言語を使っておけばよかったと後悔するわけだ。
484デフォルトの名無しさん:2006/01/30(月) 08:39:57
>>482
C++ は静的な型チェックを厳重にすることで、実行時の安全性を提供
することを大切なものだと考えているから、eval なんて動的な翻訳系は
提供できないのさ。たとえ実行時の自由度が低下したとしても、安全の
ほうが優先されるのさ。
485デフォルトの名無しさん:2006/01/30(月) 12:41:26
>>483-484
そんなこと言っておきながら、ホントはあったら嬉しいんでしょ?
まあ無名関数すらない現状じゃまだまだ先だろうけど。

>>484
evalと静的な型チェックって相反するものなの?
486デフォルトの名無しさん:2006/01/30(月) 12:48:49
コンパイル型の処理系でevalがあって何がうれしいんだ?
487デフォルトの名無しさん:2006/01/30(月) 13:09:41
>>485
コンパイラとインタプリタの違いから勉強しなさい。
488デフォルトの名無しさん:2006/01/30(月) 13:20:14
ところで、ツールにスクリプティングの機能を持たせたいとき
どんなインタプリタエンジンを組み込んだらいい?
Tcl系、Lisp/Scheme系、FORTH系とかいろいろあるけど、
サイズが小さくてよさげなものはなんだろ。
お勧めあったら教えて。
489デフォルトの名無しさん:2006/01/30(月) 13:21:59
組み込み用のインタプリタだとluaあたりが定番じゃないか?
490デフォルトの名無しさん:2006/01/30(月) 13:26:27
> そんなこと言っておきながら、ホントはあったら嬉しいんでしょ?

全然
491デフォルトの名無しさん:2006/01/30(月) 14:18:43
>>489 初めて聞いた。ブラジル産で、ポルトガル語で月、らしい。
492デフォルトの名無しさん:2006/01/30(月) 18:30:25
それにしても>>476は一体どんな風にvectorを知ったんだろう。
普通STLのコンテナの解説にはforループのサンプルもついてくると思うが
493デフォルトの名無しさん:2006/01/30(月) 18:33:28
読まない、調べない、考えない、これ常識。
494デフォルトの名無しさん:2006/01/30(月) 18:55:44
例のゆとり世代と言うやつか
495デフォルトの名無しさん:2006/01/30(月) 19:33:36
ついでに、プログラミングしない、で476は幸せになれるのになぁ
496デフォルトの名無しさん:2006/01/30(月) 19:34:19
ループを一切使わないSTL原理主義者の書いた解説かも知れんぞ
497デフォルトの名無しさん:2006/01/30(月) 21:46:02
今独習C++で独習中なのですが、何だかこの本でいいのか不安です。
もし↑読んだ方いたら、他の初心者用のと比べてどうかなど指摘して欲しいのですが。
お願いします。

//不安な点の例) 「アドレス情報を保存しなさい」という問題→ちゃんと「住所」と訳してくれないと紛らわしい('A`)
498デフォルトの名無しさん:2006/01/30(月) 21:51:28
とりあえず「アドレス帳」に文句をつけときなさい。
499デフォルトの名無しさん:2006/01/30(月) 22:00:45
C++で何やればいいの?
メッセンジャーソフト作れる?
500デフォルトの名無しさん:2006/01/30(月) 22:03:58
独習C++は読んだこと無いが、
独習JAVAはウンコだった。
501デフォルトの名無しさん:2006/01/30(月) 22:08:39
>>497
そこは「アドレス」が通称なので気にしなくてよい。
502デフォルトの名無しさん:2006/01/30(月) 22:27:41
>>501
失礼、言葉足らずでスマソ
俺もポインタのだと思って、ちゃんと作ってから答え見たら
「street」とか「city」とかの情報を文字列で保存してあったのですよ・・・('A`)
訳書なので、独習CはよかたのにC++はイマイチなのかな、と
//問題原文一部→「名前とアドレス情報を保存するクラスを作成しなさい。クラスの非公開メンバ〜〜desplay()というなまえを付けます)。」

>>500
C&C++書いた人と、Java書いた人は違うみたいでした。
Javaもいつかやるかもだから、気をつけてみます
503デフォルトの名無しさん:2006/01/30(月) 22:55:42
>>502
>desplay()

それは酷いな
504デフォルトの名無しさん:2006/01/30(月) 23:34:49
>>503
ワラタ
505デフォルトの名無しさん:2006/01/30(月) 23:53:54
確かに酷い
そこは、純粋に俺の誤植ですよ・・・('A`)

どうせもう買っちゃったわけだし、素直に全部読んでみます。
ありがとうございました
506デフォルトの名無しさん:2006/01/31(火) 01:18:22
正直なところC++は入門書1冊読んだくらいではどうにもならないから
どれでもいいと思う
507デフォルトの名無しさん:2006/01/31(火) 04:04:38
おまいらはC++の本を何冊持ってるの?
508デフォルトの名無しさん:2006/01/31(火) 04:12:10
1冊も持ってない
509デフォルトの名無しさん:2006/01/31(火) 04:21:24
習うより慣れろだにょ
510デフォルトの名無しさん:2006/01/31(火) 04:23:45
4冊。
どれも定番のみ
511デフォルトの名無しさん:2006/01/31(火) 04:37:27
初心者です。コピーコンストラクタを引数をもつコンストラクタに
書き換えることは出来ますか?あるいは出来る場合と出来ない場合があるのでしょうか?
512デフォルトの名無しさん:2006/01/31(火) 04:46:01
C++入門なら、高橋麻奈神のやさしいC++一冊+インターネットで十分だと思うよ
独習C++は激しく読みづらかった
513デフォルトの名無しさん:2006/01/31(火) 05:06:30
なんでもいいから1つプログラミング言語知ってるなら最初から禿本でいいと思うが。
あれ、結構内容浅いし。カバーしてる範囲は広いが。
514デフォルトの名無しさん:2006/01/31(火) 05:16:08
A級B型C++
515デフォルトの名無しさん:2006/01/31(火) 05:30:55
>>511
コピーコンストラクタの引数は決まってる。変更不可。
むしろ、変更したらコピーコンストラクタじゃなくなる、ってのが正しいかな。
516デフォルトの名無しさん:2006/01/31(火) 06:42:19
>>516ありがとうございます
517デフォルトの名無しさん:2006/01/31(火) 06:55:19
C++の本10冊あるが・・・
みんな以外と持ってない?
518デフォルトの名無しさん:2006/01/31(火) 07:36:40
Effective C++
More Effective C++
Effective STL
Modern C++ Design
D&E

この5冊があれば他にはいらない。
519デフォルトの名無しさん:2006/01/31(火) 07:37:03
>>517
今本棚見たら

・The C++ Programming Language
・Effective C++
・More Effective C++
・Effective STL
・Exceptional C++
・More Exceptional C++
・The C++ Standard Template Library
・Modern C++ Design
・Template Meta Programming
・The Annotated C++ Reference Manual
・Design and Evolution of C++
・Ruminations On C++
・Designing and Coding Reusable C++

が並んでた.一応10冊は超えてるけど,それでも10冊持ってるって相当のC++オタだと思うぞ.
(俺は研究上必要になったので揃えたんだが……)
520デフォルトの名無しさん:2006/01/31(火) 07:55:54
>>519
俺は英語読めないヘタレだから、
More Exceptional C++とか、
訳が糞らしいってだけで敬遠してる
More Effective C++は持ってない・・・
でもやっぱり買おうかどうか迷ってる。

でも持ってるだけで、難解すぎて読めてない本とか、
これから読む予定で予定は未定な本が半分くらいだったり
521デフォルトの名無しさん:2006/01/31(火) 07:56:41
PLCPP3rd
D&E
Boost

偏ってるなぁ俺……
522デフォルトの名無しさん:2006/01/31(火) 08:19:47
>>520
More Exceptional C++の訳書って出てるの?
523道化師:2006/01/31(火) 08:28:42
>>517
JIS X 3014 や ISO/IEC 14882 の .pdf も数に含めていいですか?

...俺、初心者向けのも結構買ってたりするし数え方次第では20冊超えるかも。

>>519
`Д´)ノ ヲタ言うな!

あと、まだ上げられてないけど

 国際規格<ISO> C++ライブラリ ハンドブック

...俺はこいつを地味に重宝してたりする。( ただし、オススメはしない。 )
524デフォルトの名無しさん:2006/01/31(火) 10:13:59
Effcetive C++ と、
ピアソンエデュケーションが出しているC++本は鉄板。

持ってるのは、

Effective C++
Exceptional C++
Efficent C++
Modern C++ Design
Effective STL
STL 標準テンプレートライブラリによるC++プログラミング 第2版
C++ ネットワークプログラミング

初心者は Accelerated C++ 読んでおけ
525デフォルトの名無しさん:2006/01/31(火) 11:00:18
本を一冊も持たず、知りたいことが出てきたら
ネットと人に本を借りることでしのいでいる俺。
あと、一番役に立つのが自分が昔書いたコードだな。

しかしコードの全文検索って、ふつうの文書と同じように
全文検索してもうまく検索できないんだよな。
あとで検索することを考えたコメント書いておかないと。
526デフォルトの名無しさん:2006/01/31(火) 12:03:00
in depth 全部
527デフォルトの名無しさん:2006/01/31(火) 15:54:11
>>522
いや、出てないから持ってないって意味
528デフォルトの名無しさん:2006/01/31(火) 17:16:42
EffectiveとEfficentはなんか数回読むだけで十分な感じがしてしまう
529デフォルトの名無しさん:2006/01/31(火) 17:19:30
JIS X3014

規格票のくせにけっこう読みやすい
530デフォルトの名無しさん:2006/01/31(火) 18:47:13
質問です。

hoge = (CHoge)hoge2;

hoge = CHoge(hoge2);

同じものだと解釈しているのですが、この認識は正しいでしょうか。
可能であれば上の場合と、下の場合で呼ばれるコンストラクタを変えたいのですが…可能でしょうか?
531デフォルトの名無しさん:2006/01/31(火) 19:01:00
>>530
その2つには違いがあると思います
前者はhoge2をCHoge型にキャストするので
((CHoge)hoge2)();と同様だと思う。コンストラクタではCHoge()が呼ばれる
後者はCHogeの引数を1つ取るコンストラクタが呼ばれる
532デフォルトの名無しさん:2006/01/31(火) 19:09:58
>>531
> ((CHoge)hoge2)();と同様だと思う。
・・・いや、それは違うだろう。
533デフォルトの名無しさん:2006/01/31(火) 19:13:21
>>531
お返事ありがとうございます。
ただ、引数をとるコンストラクタが呼ばれるようです。

今のところ両方とも
CHoge(const CHoge2& hoge);
が呼ばれます。
534デフォルトの名無しさん:2006/01/31(火) 19:15:56
>>530
CHoge が hoge2 の型を取るコンストラクタを持ったクラス型なら、
どっちでも同じになりそう。

CHoge と hoge2 の意味に前提が無ければ、ちょっとだけ違うような気がする。
後者は static_cast<CHoge>(hoge2) と同じ。
前者は static_csat がダメでも const_cast, reinterpret_cast になるかもしれない。
535デフォルトの名無しさん:2006/01/31(火) 19:18:35
>>530
試してみた結果、

hoge2 も CHoge 型だとすると
・(CHoge)hoge2 は何もしない。
・CHoge(hoge2) はコピーコンストラクタが呼ばれる。

hoge2 が CHoge 型ではないとすると
・(CHoge)hoge2 も CHoge(hoge2) も hoge2 の型を引数にとるコンストラクタが呼ばれる。

あとはどの場合も代入演算子のオーバーロード関数が呼ばれる。
536デフォルトの名無しさん:2006/01/31(火) 19:22:34
(ノ∀`)アチャー やはり同じになってしまいますか。

JAVAの記述法をC++で再現という(意味の無い、C++の理解を深めるための)アソビをしておりまして。

DataInputStream型 と InputStream型を作ったのですが困っていたのです。
dis = (DataInputStream)is;
とやれるように作った(ダウンキャストを再現)はいいのですが、DataInputStreamのコンストラクタには普通にInputStreamを引数にするものがあるのです。

(DataInputStream)で変換された場合は「そのまま内部ポインタをコピー」すればいいのですが、
InputStreamを普通に引数にとるコンストラクタなら「InputStreamに無くてDataInputStreamにあるデータの初期化」も必要となります。

これは手詰まりかな…。

537デフォルトの名無しさん:2006/01/31(火) 19:26:50
なんて無駄かつ楽しそうなんだろうw
538デフォルトの名無しさん:2006/01/31(火) 20:53:10
hoge2が operator CHoge &() なんて類のメンバ関数を持ってても違いはでないんだっけ?

# コンストラクタに explicit の指定がないと曖昧だって言われてエラーになるような気もするけど。
539デフォルトの名無しさん:2006/01/31(火) 21:52:52
質問です。
何もライブラリが利用できない環境でC++を利用したい場合(組み込みとかOS等)
C++の言語の機能(ライブラリは除く)をフルに使うには何を実装すればよいかの
情報ってどこかにありませんか?

例えばnewやdeleteの中身は実装しないとC++は利用できないですよね。
540デフォルトの名無しさん:2006/01/31(火) 21:56:23
>>539 例外処理もいるよな。
541デフォルトの名無しさん:2006/01/31(火) 22:01:49
>>539
規格書を読めば逆に何を実装しなければならないかと言うことは書いてある。
組み込みのような環境は自立処理系などと言う呼称で一部のライブラリだけ用意されていればよいことになっている。
542デフォルトの名無しさん:2006/01/31(火) 23:16:11
>>540
組み込みで例外処理を独自に実装するのは、
よほどのチャレンジャーじゃない限り現実的じゃないぞ
543デフォルトの名無しさん:2006/02/01(水) 01:22:57
標準関数って std 名前空間の下にあるんですよね?
using namespace std; していなくても、
getchar() とか普通に使えるんですが・・・
もちろん std::getchar() でも使えるんですけど、
これじゃグローバルにあるのと変わらない気がします。
std 名前空間だけ特別扱い??
544デフォルトの名無しさん:2006/02/01(水) 01:24:40
釣りなら釣りとメールr
545デフォルトの名無しさん:2006/02/01(水) 01:31:14
(;゚д゚) ・・・
 
(つд⊂)ゴシゴシゴシ
  _, ._
(;゚ Д゚) …!?
546デフォルトの名無しさん:2006/02/01(水) 01:39:03
>>543
#include <stdlib.h>

#include <cstdlib>
の区別はついてる?
547デフォルトの名無しさん:2006/02/01(水) 01:41:31
>>546 はい、#include <cstdlib> しかしていなくても、
getchar() や ::getchar() が使えるんですが、
これは使用なんでしょうか?
548デフォルトの名無しさん:2006/02/01(水) 01:44:43
>>543
コンパイラは?まずはそこからだ
549デフォルトの名無しさん:2006/02/01(水) 01:47:25
#include <cstdlib>
#include <iostream>

int main(const int argc, const char* const  argv[]){
    std::cout << "えんたぁおして";
    ::getchar();
    return EXIT_SUCCESS;
}

このコードが通るので、何でだろうと思いました。
Visual C++ 2005 を使っています。
550デフォルトの名無しさん:2006/02/01(水) 02:00:17
>>549
それはね、C++の規格書のmissなんだよ。現在では修正されていたはずだけど。
551デフォルトの名無しさん:2006/02/01(水) 02:07:43
むしろ、VC2005の"cstdio"とかはstd名前空間に入ってないんじゃ。

#ifdef _STD_USING
#undef _STD_USING
#include <stdio.h>
#define _STD_USING

#else /* _STD_USING */
#include <stdio.h>
#endif /* _STD_USING */

"stdio.h"の内部に_STD_USINGに関する#ifディレクティヴなし。

意味あんのかこれ……。
552デフォルトの名無しさん:2006/02/01(水) 02:13:01
#include <cstdlib>

int main(const int argc, const char* const  argv[]){
    ::getchar();
    return EXIT_SUCCESS;
}

これだと getchar はグローバルな名前空間にないと怒られる。
Visual C++ 2005
553デフォルトの名無しさん:2006/02/01(水) 02:21:55
>>552
分かっているとは思うけど
cstdlibには標準入出力は定義されていない。
cstdioならグローバルな空間を汚染する。
>>549の場合iostreamが暗黙的にcstdioをincludeしてるから可能だった。
554デフォルトの名無しさん:2006/02/01(水) 02:33:04
あ、cstdioとcstdlibを読み違えてた。ていうか、なぁんで
cstdioはglobalに放り込むかなぁ
555553:2006/02/01(水) 03:01:25
>>554
グローバル空間を汚染しない実装も可能だけど現実の問題として
C/C++両方のヘッダを弄るのが面倒なので

stdio.hはCのままで
cstdlibで

#include<stdio.h>
namespace{
  using ::getchar;
  using ::putchar;
  ......
}
こんな感じの実装をしてるのが原因だな。
ちなみにVC以外の他の多くのコンパイラでも同じような状況。
だからC言語の名前とだけは、
ぶつからないように定義しとかないと問題が発生しやすい。
556デフォルトの名無しさん:2006/02/01(水) 03:07:08
何回やるんだよこのネタ。
557デフォルトの名無しさん:2006/02/01(水) 03:11:56
>>556
「STLを使うと〜」のテンプレにみたいうまいことまとめてくれw
558デフォルトの名無しさん:2006/02/01(水) 15:59:52
質問です。
int a[] = {0, 0, 0, 0};
のような {x, y, z}という初期化パラメータ記述は、独自クラスででも使えるのでしょうか?
使えるなら記述法を知りたいのです。
559デフォルトの名無しさん:2006/02/01(水) 17:33:47
>>558
コンストラクタがなくて、メンバが全てパブリックなクラスなら使える。
560デフォルトの名無しさん:2006/02/01(水) 17:44:21
>>559 ほとんど構造体だな。
561デフォルトの名無しさん:2006/02/01(水) 19:26:35
文字列の簡単な解析をしているのですが,数値は数値として,
文字列は文字列としてVectorなどに格納したいと思っています.

現在はとりあえず全てstring型に変換してvector<string>へ格納し,
そのつど数値かどうか判定し数値ならばatofなどで変換をしています.
そのつど変換したり判定したりする部分がちょっとややこしいので
できればそのまま格納してやりたいのですが何か良い方法はないでしょうか?
562561:2006/02/01(水) 19:28:51
>>561の補足です

すいません,簡潔に言うと,同じ1つのvectorに
複数の異なる型を入れたいと思っています.

vector<???> v;
v.push_back(10);
v.push_back('*');
v.push_back(23.5);
563デフォルトの名無しさん:2006/02/01(水) 19:30:15
>>561
boost::variant
564デフォルトの名無しさん:2006/02/01(水) 19:31:18
>>561
boost::any
565561:2006/02/01(水) 19:40:42
>>563-564
おお,便利そうですね.これで解決できそうです.
ありがとうございました.
566デフォルトの名無しさん:2006/02/01(水) 19:45:39
なーんか設計見直したほうが最終的に良い予感がしてならないけどな
(保守・教育双方の観点から)
細かい事情が分からないからあまり突っ込んだことは言えないが
567561:2006/02/01(水) 20:24:15
>>566
計算式が入っている文字列、例えば "10*(23.5-2)" を読み込んで
計算結果を得るものを作っています。
568デフォルトの名無しさん:2006/02/01(水) 20:34:10
boost でメタプログラミングするのはどうよ。
569デフォルトの名無しさん:2006/02/01(水) 20:35:52
出たなランバダブラザーズ
570デフォルトの名無しさん:2006/02/01(水) 21:10:41
ん?ラムダブラザーズ?
571デフォルトの名無しさん:2006/02/01(水) 21:39:42
ワンダバスタイル?
572デフォルトの名無しさん:2006/02/01(水) 22:49:13
見えないブラザーが保護者のようにキミを見る
573デフォルトの名無しさん:2006/02/01(水) 23:33:11
>>517 >>518 >>519
ここは自分の本棚を晒すスレですか?

・The C++ Programming Language
・Effective C++
・More Effective C++
・Effective STL
・Exceptional C++
・The C++ Standard Template Library
・Modern C++ Design
・Design and Evolution of C++
・C++ FAQ第2版
・C++ 再考
・C++ 標準的コーディング技法
・C++ Coding Standards
・Boost C++ Libraryプログラミング
・C++によるXML開発技法
・C++プログラミングの落とし穴

しかし、よくここまでよく揃えたものだ。
C++がお気に入りってのもあるけど。

でも、まだModern C++ Designは理解できない。orz

>>523
わーい、道化師さんだ〜!!
574デフォルトの名無しさん:2006/02/02(木) 00:25:51
ほんの話題が出ているようなので、
便乗で質問しますが、

どういう風にクラスを作ればよいのか、とか、
継承や多重継承の有効な使い方を解説した本でお勧めはありませんか?

575仕様書無しさん:2006/02/02(木) 00:30:33
継承とか一通り解っているのなら
「オブジェクト指向のこころ」
576デフォルトの名無しさん:2006/02/02(木) 00:35:54
「さ〜これからバリバリプログラミングの勉強するぞ〜」
っていう初心者に一番最初に教えるべき事は

「まず、プログラムを新しく書かずに済む方法を考えろ」
577574:2006/02/02(木) 00:36:26
>>575
一応、C++の文法は一通り書いて、覚えてみたのですが、
どういう風にクラスを書いてよいのか、思いつかないのです。
578デフォルトの名無しさん:2006/02/02(木) 00:41:09
>>577
OOP的設計の仕方が分からんのか?
それなら憂鬱なryをお勧めする
わかりやすいし読んでて面白い
579仕様書無しさん:2006/02/02(木) 00:41:21
>>577
ちょいと(かなり?)背伸びするのなら
「アジャイル開発の奥義」

どうせならモダンなooの本を
580デフォルトの名無しさん:2006/02/02(木) 00:42:59
クラスってのは手段であって、目的じゃない。
やりたいことを明確にすれば、どういうクラスを書けばいいかわかるよ。
あとはある程度の量をこなさないと駄目だね。とにかく書く。
そのうち「あ、そういうことか」という瞬間が訪れるよ。
ま、やってみなはれ。
581仕様書無しさん:2006/02/02(木) 00:44:28
高凝集度と疎結合が書いてある本が良い
582デフォルトの名無しさん:2006/02/02(木) 00:47:53
>>574
オブジェクト指向本って、Javaを念頭において書かれてるのが多くて
やたら継承を多用してたり、仮想関数や動的解決に依存した
スタイルだったりするよな。

でも、C++はそれとは逆にテンプレートと静的解決の
ジェネリックプログラミングに向かってるから、
C++の勉強でOOP本を薦めるのは痛し痒しってとこだな。

583574:2006/02/02(木) 00:55:19
確かに、いまはC++ Template Metaprogrammingという本にハマっているのですが。
今まで敬遠してきたboostが、ものすごく面白いライブラリに思えています。

ただ、boostの実装方法は、さっぱり理解できません。
ソースを読んでもさっぱり。
使う分には、簡単なのですが。
584仕様書無しさん:2006/02/02(木) 00:56:04
言われてみれば、>>575はJAVAの本だったorz
クラス設計の観点からは同じな部分多いんだけど
585デフォルトの名無しさん:2006/02/02(木) 01:02:55
boostの中身は魔法の呪文
586デフォルトの名無しさん:2006/02/02(木) 01:05:49
さすがにboost::arrayあたりは簡単だぞ
587デフォルトの名無しさん:2006/02/02(木) 01:18:43
今までなんでもかんでもオブジェクト指向で動的解決させてきたのが
ジェネリックプログラミングで静的にも解決させたほうがいい場面もある、って流れだろ?
基本文法→オブジェクト指向→ジェネリックって流れがいいと思うけどなぁ
588デフォルトの名無しさん:2006/02/02(木) 01:35:05
>>539
C++まで行くか知らないが
ttp://libc.blog47.fc2.com/
とか…?
589デフォルトの名無しさん:2006/02/02(木) 09:56:21
>>583
それ、読んでみたいけど、日本語版はまだないよね?
洋書でもいいんだけど、翻訳版が出そうな気がして手を出しづらい。
590デフォルトの名無しさん:2006/02/02(木) 10:04:28
MPLの作者が本書いたのか。知らなかった。
591デフォルトの名無しさん:2006/02/02(木) 12:42:38
std::string str;
  :
const char* p = str.c_str();

strが変更や破棄されない限り、pが指す先が有効である事は保証されているのでしょうか?
localtimeの様にバッファを共有していて、別オブジェクトのc_str()呼び出しで
内容が変わったりする実装があったりするんでしょうか?
592デフォルトの名無しさん:2006/02/02(木) 12:59:29
593デフォルトの名無しさん:2006/02/02(木) 13:01:46
boost::mplよりTypeListの実装の方がカッコいい
594デフォルトの名無しさん:2006/02/02(木) 13:59:23
>>592
21.3.5じゃなくて21.3.6ですよね?

>21.3.6 - basic_string string operations [lib.string.ops]
>-2- Requires:
>Nor shall the program treat the returned value as a valid pointer value
>after any subsequent call to a non-const member function of the class basic_string
>that designates the same object as this.

ここの部分の翻訳に自信が無いんですが
「同じオブジェクト」の非constメンバを呼ぶまでポインタは有効
ってことでいいんでしょうか?
595デフォルトの名無しさん:2006/02/02(木) 15:24:23
>>594
21.3.6 basic_string string operations [lib.string.ops]
プログラムは配列に格納された値のいずれも変更しないものとする。
また、プログラムは、(c_str()の呼び出し時の)thisと同じオブジェクトを指す
basic_stringクラスの非constメンバ関数に対して、
その後のどんな呼び出しの後にも有効なポインタ値として戻り値を扱わないものとする。

→ 非constメンバ関数が呼び出された後は有効でなくなる。constメンバ関数については未定義。
596デフォルトの名無しさん:2006/02/02(木) 16:46:41
>constメンバ関数については未定義。

マジっすか?
非constメンバ呼び出し→以前のc_str()で得たポインタは有効でなくなる
そうでないなら(constメンバ呼び出しなど)→以前のc_str()で得たポインタは有効のまま
と解釈できると思うんだけど。
597デフォルトの名無しさん:2006/02/02(木) 20:05:54
そうえいば、以前 cppll だか、 vcppML だかで、実装によっては c_str() を使った
インスタンスをコピーしたインスタンスが書き換えられただけで無効になってしまうとかで
こんなんじゃ使いモンなるかー、ゴルァ(゚Д゚)って話を見た気がする・・・
確か、エピたんがSTLのヘッダのどこそこのオプション弄ればこの問題を回避できるとかって
言ってたようなとこまでは覚えてるんだけど・・・
かなり曖昧な記憶なんで、俺の記憶違いかも知れん。
598デフォルトの名無しさん:2006/02/02(木) 21:16:48
>>589
おそらくでないから。翻訳したところでマニアックな人にしか売れないから。
だから買おうね。
599デフォルトの名無しさん:2006/02/02(木) 21:17:26
21.3.6以外にbasic_stringのc_str()に関する記述がなければ、未定義ということになる。
constメンバ呼び出しなら変わらないと期待できそうだけれど、
実装の仕方によっては変わることもあり得る(効率のために)。
毎回c_str()を呼び出すか、自分が使用するコンパイラの実装を確認するしかないんじゃないかな。
600デフォルトの名無しさん:2006/02/02(木) 23:53:48
そこでvector<char>
601デフォルトの名無しさん:2006/02/03(金) 00:30:04
つーか毎回c_str呼んでなんか不都合あるのか?
602591:2006/02/03(金) 00:45:12
>>601
suffix arrayに登録するのに、文字列中の各文字へのポインタが必要なんですよ。
std::vector<char>にコピーして使えばいいんですけど
文字列を重複して持つ事になるのは嫌だったので。
603デフォルトの名無しさん:2006/02/03(金) 08:39:51
俺も std::string を「凍結」して内部バッファを
取り出せたら便利だなぁ、と思ったことがある。

結局 c_str() で取り出して(一時的に文字列を重複して持つ)、
すぐ std::string を破棄することにした。
っていうか、>>591 は c_str() で取り出した後も
ずっと std::string を保持し続ける必要があるの?
604デフォルトの名無しさん:2006/02/03(金) 08:41:42
suffic array のライブラリの方を、
std::string を受け取って c_str() 毎回呼び出すように
改造するとか、どうよ。

って、今度は std::string 自体が重複するようになるだけか。
そうすると boost::shared_ptr<std::string> とかか。
605デフォルトの名無しさん:2006/02/03(金) 09:19:31
昔、自分自身は文字列を持たずに元文字列への参照を持つ部分文字列クラスとか考えたことあるな。
606デフォルトの名無しさん:2006/02/03(金) 12:48:17
正直、マルチスレッドが普及した今、
std::basic_stringの、refcountを前提とした設計は、時代遅れ。
素直に毎回バイト列をコピーして、スレッド内でのconst性を
確保したほうがマシ。
607デフォルトの名無しさん:2006/02/03(金) 18:10:55
短い文字列(短いといっても数100文字以下程度で多くの場合が該当)だと
deep copy + fast allocation + 短文字列最適化 で
スレッド安全な参照カウント実装での速度に十分到達できるか,
場合によっては outperform できるらしいですしね.
ここら辺の議論は GotW あるいは"More Exceptional C++" で
具体的な数字出して比較されています.

http://www.gotw.ca/publications/optimizations.htm

suffix array のような使い方だと,空間的な効率も似たりよったりか,
場合によっては deep copy の方が高効率かも知れませんし.
ただ,スレッド安全性を前提にしなくて良い場合もあるでしょうし,その場合の
参照カウントは有意な高速化が望める可能性があるとは思いますけれど.
608デフォルトの名無しさん:2006/02/03(金) 18:15:50
なんでthisは参照じゃなくてポインタになったんだろ-?
参照だったら「delete thisはしていんんですか?」「this=&rhsはしていんんですか?」問題なぞ発生しなかったろうに・・・
609デフォルトの名無しさん:2006/02/03(金) 18:23:05
>>608
C++ではthisという仕組みが先に出来て、
参照という仕様が出たのはそれよりもずっと後だから。
610デフォルトの名無しさん:2006/02/03(金) 18:23:41
その頃には参照なんてなかったのさ
611デフォルトの名無しさん:2006/02/03(金) 18:24:53
>>609
結婚しようか
612デフォルトの名無しさん:2006/02/03(金) 18:25:23
>>611
だが断る!
613デフォルトの名無しさん:2006/02/03(金) 18:29:26
ちょwwおまwwwww
614デフォルトの名無しさん:2006/02/03(金) 18:55:55
std::stringstream ss("abc");

std:istreambuf_iterator<char> it1(ss); it1++;
std::istreambuf_iterator<char> it2(it1); it1++;

std::cout << *it1;
std::cout << *it2 << std::endl;

実行結果:
cc

cbを期待していたのですが、私は何か間違っているでしょうか??
615デフォルトの名無しさん:2006/02/03(金) 19:09:56
>>614
istreambuf_iteratorはInputIteratorであってForwardIteratorではないから、
イテレータのコピーを取ってそれらを同時に操作しようとしても
期待した結果にはならない。
616デフォルトの名無しさん:2006/02/03(金) 19:39:28
>>614
InputIterator は、一度 dereference すると、その状態は保障されない。

InputIterator it = ...
InputIterator itDash = it;
bool a = ( *it == *itDash );

としたとき、a == true は保障されない。
617デフォルトの名無しさん:2006/02/03(金) 20:06:19
>>616
InputIterator は複数回の dereference が保証されていないのではなく
traverse 後のコピーの状態が保証されていないです.

>InputIterator it = ...
>InputIterator itDash = it;
>bool a = ( *it == *itDash );

での a == true は保証されていると思いますが,

value_type v = *it;
itDash = it;
++it;
bool b = ( *itDash == v );

での b == true が保証されていないというか,このときに itDash に
operator* を 適用できること自体がそもそも保証されていないです.
618デフォルトの名無しさん:2006/02/03(金) 21:19:42
すみません.
プログラミング言語 C++ 第3版を見ながら学習しているんですが,
等号演算子のオーバーライドで,

class X
{
// ...
const operator ==( X&, X& );
とするとコンパイルエラーになるんです.

「エラー E2080 cmem.cpp 74: 'CMem::operator ==(CMem &,CMem &)' は引数 1 つで宣言し
なければならない」

なぜなんでしょうか…
619デフォルトの名無しさん:2006/02/03(金) 21:21:01
きみは、X x,y,z;に対して、x.operator==( y,z )と呼びたいのかね?
620618:2006/02/03(金) 21:24:06
誤)
class X
{
// ...
const operator ==( X&, X& );
正)
class X
{
// ...
const bool operator ==( X&, X& );
}
621618:2006/02/03(金) 21:26:30
> X x,y,z;に対して、x.operator==( y,z )と呼びたいのか

すみません, もう少し詳しくお願いします.
622デフォルトの名無しさん:2006/02/03(金) 21:27:42
それで分からないんだったらやめた方がいいと思う
623デフォルトの名無しさん:2006/02/03(金) 21:31:30
>>621
ヒント:==は3項演算子ではない。


そういうことがやりたければ、クラスの外に出せばいい。
624618:2006/02/03(金) 21:39:00

クラスの外に出せばいいのか...
了解です.
625618:2006/02/03(金) 21:57:32
T1 operator @( T2 )
の T1 は,
a @ b
の a に当たるのではなくて,
演算子 @ が返す型だったということで解決.
626デフォルトの名無しさん:2006/02/04(土) 01:17:19
おいおい
627デフォルトの名無しさん:2006/02/04(土) 01:26:07
わかったからよしとしよう
628デフォルトの名無しさん:2006/02/04(土) 04:14:03
CでいきなりK&Rが無理じゃないのと違ってC++でいきなり禿本はきっつい。
629デフォルトの名無しさん:2006/02/04(土) 05:07:06
そう?
630デフォルトの名無しさん:2006/02/04(土) 12:47:40
Effective C++はちょっと当たり前すぎる感じがしたな。
むしろMore Effective C++が勉強になった
631592:2006/02/05(日) 16:26:13
>>594-607
おそくなって申し訳ないけども、リンク先の 21.3 -5- のことを指したかったんだ。
お詫びにこんなのも拾ってきたよ。
ttp://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#263
632デフォルトの名無しさん:2006/02/05(日) 21:54:29
C++の仕様書を読んでいます。(ISO/IEC 14882 First edition 1998-09-01)

関数の定義の仕様(8.4 Function definitions)を読んでいたのですが、

function_definition:
decl_specifier_seq( opt ) declarator ctor_initializer(opt) function_body

こんな感じで書かれています。
ここの、decl_specifier_seq が関数の戻り値の型に相当するようです。(8.4.2のExample参照)
で、これは7.1(Specifiers)で、以下のように定義されています。

decl_specifier_seq:
decl_specifier_seq(opt)
declspecifier

つまり、複数の declspecifier を含むことができるようになっています。
でも、それを額面どおりに受け取ると、戻り値型を複数指定できる、と
読めるのですが、もちろんそんなことはありませんよね?

int char Foo( ... )

とかはコンパイル通りませんし。なぜ仕様書ではこんな書き方になっているの
でしょうか?なにかを見落としているなら、教えてください。
それとも、ひょっとして複数型の戻り値が仕様的には正しいwのでしょうか?
ちなみに、decl_specifierにint とか charが含まれます。
よろしくお願いします。
633632:2006/02/05(日) 22:00:33
8.4.2 のサンプルは、以下の通りです。

Example: a simple example of a complete function definition is

int max(int a, int b, int c)
{
int m = (a > b) ? a : b;
return (m > c) ? m : c;
}

Here int is the decl_specifier_seq;
max(int a, int b, int c) is the declarator; { /* ... */ } is
the function_body.
634デフォルトの名無しさん:2006/02/05(日) 22:03:24
>>632
7.1.5(Type specifiers) -1- より
"As a general rule, at most one type-specifier is allowed in the complete decl-specifier-seq of a declaration."

ttp://www.kuzbass.ru/docs/isocpp/dcl.html#dcl.type
635632:2006/02/05(日) 22:07:56
>>634
感謝感激です!
636デフォルトの名無しさん:2006/02/06(月) 02:37:00
typedefを用いて定義した型の前方宣言(previous declaration)はどのようにしたらよいですか?

具体的には item.h が次のようになっていて

class Item
{
 // いろいろ
};
typedef std::list<Item> List;

別のヘッダファイル内でこの item.h をincludeせずに List を前方宣言したいのですが、
class List;
とか
typedef struct List;
とかすると型が一致しないと怒られてしまいます。

item.hをインクルードするしかないのでしょうか。
解決法があれば教えてください。
637デフォルトの名無しさん:2006/02/06(月) 02:55:34
>>636
面倒なのを厭わなければ、

class Item;
typedef std::list<Item> List;

という内容のitem_fwd.hを作って、item.hとItemの前方宣言が必要なファイルの両方からインクルードするという方法がある。
638デフォルトの名無しさん:2006/02/06(月) 03:18:40
これって実装の問題? それとも規格でそうなってんの?
639636:2006/02/06(月) 06:49:40
>>637

なるほど、ありがとうございました。
640デフォルトの名無しさん:2006/02/06(月) 11:26:34
>>636,637
不完全方を引数にした標準テンプレートのインスタンス化による効果は未定義。
というわけで、標準コンテナを使ってる限り、その形で前方宣言は無理。

class Item;
typedef std::list<Item*> List;

これなら大丈夫。
641デフォルトの名無しさん:2006/02/06(月) 16:42:13
>>640
>不完全方を引数にした標準テンプレートのインスタンス化による効果は未定義。
未定義っつうかインスタンス化しようとしたところでコンパイルエラーになるのでは?
ちなみに637の内容はインスタンス化じゃないよね
642640:2006/02/07(火) 01:57:55
>>641
ふむ。 typedef では完全な定義は要らないのでインスタンス化は起こらなさそうだな。
ただ、規格中にはっきりとした記述が見当たらない。

未定義じゃなくてコンパイルエラーになってくれればいいんだけど、例えば

class T
{
public:
 ... // public interface
private:
 class Impl;
 std::auto_ptr<Impl> pimpl;
};

なんて pimpl の雛型を書くと、ほとんどの実装でコンパイルは通るが
厳密に規格と照らし合わせると未定義動作になる。
643デフォルトの名無しさん:2006/02/07(火) 03:06:40
>>642
>ただ、規格中にはっきりとした記述が見当たらない。
これが正しいかどうかは検証が大変なので置いといて

>なんて pimpl の雛型を書くと、ほとんどの実装でコンパイルは通るが
>厳密に規格と照らし合わせると未定義動作になる。
Tのインスタンスを作ろうとするとT::Implの定義が必要でコンパイルエラーになる
インスタンスがないものは動作しようがないので(たぶん)未定義動作は起こらない
のでは?
644デフォルトの名無しさん:2006/02/07(火) 03:11:03
>642
コンパイルエラーにならないのは、pimplがポインタ変数(ポインタのサイズ
はポインタが指すオブジェクトのサイズに無関係)だからだろ?

std::auto_ptr<Impl> pimpl;



Impl impl;

だったらコンパイルエラーになる。Implの宣言が読み込まれていない
(sizeof(Impl)が不明な)状態で、sizeof(T)はいくつ?

645デフォルトの名無しさん:2006/02/07(火) 03:24:13
>>643
> Tのインスタンスを作ろうとするとT::Implの定義が必要でコンパイルエラーになる
それ、やってみて言ってる?エラーメッセージは?
手元のコンパイラ2つでは、両方とも警告しか出ない。
646デフォルトの名無しさん:2006/02/07(火) 03:24:47
>>644
それはわかってる。
auto_ptr<Impl> がコンパイル通るのに、実際には
規格で許されていないのが今の問題。
647デフォルトの名無しさん:2006/02/07(火) 03:29:11
一般に、C<T>をインスタンス化するためにTが完全な型である必要があるかどうかは
Cの実装に依存する。(インスタンス化した文脈と処理系にも依存したかもしれない)
だから、標準ライブラリのテンプレートに不完全な型を渡すと、
標準ライブラリの実装によってコンパイルの可否が左右される。
そこで、規格は、そういう実装依存のコードを避けるため、
標準ライブラリのテンプレートに不完全な型を渡すこと自体を禁止したのではないかと。

>>643
>Tのインスタンスを作ろうとするとT::Implの定義が必要でコンパイルエラーになる
g++3.4.2では警告だけ。

>>644
コンパイルエラーにならない原因はその通りだけど、
>>642はエラーにならないこと自体を問題視してるんだと思われ。
648デフォルトの名無しさん:2006/02/07(火) 03:29:56
>>645
訂正
>Tのインスタンスを作ろうとするとT::Implの定義が必要でコンパイルエラーになる
T::Implのインスタンスを作ろうとするとT::Implの定義が必要でコンパイルエラーになる
649647:2006/02/07(火) 03:30:13
ごめん。とてもかぶった。
650デフォルトの名無しさん:2006/02/07(火) 03:32:03
>>647
>標準ライブラリのテンプレートに不完全な型を渡すこと自体を禁止したのではないかと。
禁止したの?
ソースを
651デフォルトの名無しさん:2006/02/07(火) 03:33:34
>>648
それは当たり前。今回の問題とは関係ない。
652デフォルトの名無しさん:2006/02/07(火) 03:33:38
>>650
表現がおかしかった。正確には>>640
>不完全方を引数にした標準テンプレートのインスタンス化による効果は未定義。
のこと。
653デフォルトの名無しさん:2006/02/07(火) 03:42:20
>>642
それ未定義動作を起こす可能性のあるソースって書ける?
642の例はインスタンス作ってないから動作しないよね
654デフォルトの名無しさん:2006/02/07(火) 03:46:17
>>653
それなら "public interface" を空にしてインスタンスの生成を追加すれば十分。
655デフォルトの名無しさん:2006/02/07(火) 03:52:46
>>654
class T
{
private:
 class Impl;
 std::auto_ptr<Impl> pimpl;
};
int main
{
T t;
}
これ未定義動作なの?
656デフォルトの名無しさん:2006/02/07(火) 04:02:57
>>655
そういうこと。(コンパイル通るように微調整すれば)
657デフォルトの名無しさん:2006/02/07(火) 04:04:57
結論としては、item.h をインクルード汁ってことか?
658デフォルトの名無しさん:2006/02/07(火) 04:07:36
>>657
違う。>>641参照。
659デフォルトの名無しさん:2006/02/07(火) 04:45:05
実際問題として、
Tのデストラクタ内でauto_ptrが delete p する必要があるでしょ。

で、この時に、Impl::~Impl()が実装されているのかどうか(呼び出すべきかどうか)が
コンパイラには判断できない。
(Implが実はPODのデータオンリー場合は、delete演算子はoperator delete()を呼ぶだけ)
で、多分(警告だけで済むってことは)、~Impl()を呼ばないコードを生成する。


・・・と思うんだけど、違うかな。
660デフォルトの名無しさん:2006/02/07(火) 05:05:29
「655が未定義動作を起こすかどうか」を分解すると
以下の(1),(2),(3)がそれぞれ未定義動作を起こすかどうかに帰結すると思う
(2)は確認してないけど多分問題ないよね.
659の指摘で(3)が通るのはいままで気づかなかった.

class A;
template <typename T> struct Hoge{};
int main ()
{
Hoge <A> h; // (1)
A *p; // (2)
delete p; // (3)
return 0;
}

661デフォルトの名無しさん:2006/02/07(火) 05:14:43
>「655が未定義動作を起こすかどうか」を分解すると
>以下の(1),(2),(3)がそれぞれ未定義動作を起こすかどうかに帰結すると思う
>>665の問題は「標準ライブラリの」テンプレート限定だから、それは違うんじゃないか?
662デフォルトの名無しさん:2006/02/07(火) 05:26:51
>>661
665は655の誤植として

それって「標準ライブラリの」テンプレートとその他のテンプレートで
振る舞いを変えるように規格で決められてるってこと?
それは不自然だと思うなぁ.
ソースがあるならよろしく
663デフォルトの名無しさん:2006/02/07(火) 05:32:49
>>658
いや、だから、item.h をインクルードして、
Item の定義をちゃんとしておけば大丈夫なんじゃないの?
664デフォルトの名無しさん:2006/02/07(火) 05:43:25
>>663
636の問いが
>item.hをインクルードするしかないのでしょうか。
だから663で問題が起こらなくとも636の答えにはなってない
665デフォルトの名無しさん:2006/02/07(火) 06:29:08
>>662
そうじゃない。 >640,652 が正解。

ほれ、ソースだ。17.4.3.6/2
http://www.kuzbass.ru/docs/isocpp/lib-intro.html#lib.res.on.functions
666デフォルトの名無しさん:2006/02/07(火) 06:55:24
でも>637は、ただ別名を定義しただけで、インスタンス化してる訳じゃない。
std::list<不完全型>自体を不完全型的に扱う限り、合法なんじゃないの。
667デフォルトの名無しさん:2006/02/07(火) 07:41:45
typedefした時点でインスタンス化が行われるとか云う話を、昔に聞いたことがあった。
というわけで、#defineでよくね?
668デフォルトの名無しさん:2006/02/07(火) 14:55:42
>>664
だから、「item.h をインクルードするしかない」という答えになるんじゃね?

>>667
#define しても、結局それを使う所で問題が起こると思われ。
ヘッダ内で使うと思うし。
669デフォルトの名無しさん:2006/02/07(火) 15:11:35
>>668
664の時点では637と640が提案されていて
637が合法かどうかは議論中であるが
640の提案に異存のあるレスはない
従って「item.h をインクルードするしかない」という答えにはならないヨ

>>667
>typedefした時点でインスタンス化が行われるとか云う話を、昔に聞いたことがあった。
これも規格中にソースを欲しいですね(私も探してますけど)

637といい642といい結構私は常用してるのですが
あんまりみなさん議論に乗ってこないとこ見るとやらないのかな?
pimplが非合法なんて影響でかいと思うのですが...
670デフォルトの名無しさん:2006/02/07(火) 15:22:43
pimplしたいならboost::shared_ptr使えば良いじゃない。
これは不完全型でも大丈夫だから
671デフォルトの名無しさん:2006/02/07(火) 15:44:58
>>670
ソースみたらboostのsmart_ptrは対策をしてあるようですね
pimplだったらscoped_ptrの方がいいのかな
672デフォルトの名無しさん:2006/02/07(火) 15:46:02
>>669
17.4.3.6/2 は標準ライブラリの話だよね。
おれは大体 pimpl に scoped_ptr 使うからどーでもいい。
673デフォルトの名無しさん:2006/02/07(火) 15:49:42
std::tr1::shared_ptr は問題が起こらないだろうけど、
標準ライブラリだから不完全型を使うと非合法になるのだろうか。
674デフォルトの名無しさん:2006/02/07(火) 16:14:19
いずれは boost:: じゃなくなりまするのか?
675デフォルトの名無しさん:2006/02/07(火) 19:34:39
>>669
>640の提案が>636の欲しかったものだとは思わないな。完全に違う実装だろこれ
でも正直、厳密な規格だのライブラリの実装だのを気にするくらいなら
不完全型を使うの控えて>640にするか素直に全部インクルードするな俺は
676デフォルトの名無しさん:2006/02/07(火) 20:21:51
std::string s;
std::cin >> s;

って具合に次々に文字列を読み込んでいくと、
確かに空白で区切られて読み込まれるんだけど、
改行した、ってのは認識できないですよね?
std::cin.peek() == '\n' とかで判定するんですか?
677デフォルトの名無しさん:2006/02/07(火) 20:27:11
>>676
std::getlineはだめ?
678デフォルトの名無しさん:2006/02/07(火) 20:34:43
ええ、あなた程度でも思いつくような事はさすがにやってます^^;;
679デフォルトの名無しさん:2006/02/07(火) 20:37:50
>>677 できれば全部 >> で出来たら便利だなぁと。
getline 使ってみますね。
680これがエラーになるのはなぜでしょうか?:2006/02/07(火) 20:51:22
namespace N {

class C {
public:
C(){}
friend std::istream operator>>(std::istream&, C&);
friend std::ostream operator<<(std::ostream&, const C&);

}; // class C
}//namespace N
681すみません、整形し直しました:2006/02/07(火) 20:51:53
namespace N {

class C {
public:
    C(){}
    friend std::istream operator>>(std::istream&, C&);
    friend std::ostream operator<<(std::ostream&, const C&);

}; // class C
}//namespace N
682デフォルトの名無しさん:2006/02/07(火) 20:57:12
エラーメッセージくらいよく読め
683デフォルトの名無しさん:2006/02/07(火) 21:40:51
ポインタを使用してa_typeというオブジェクトの配列にアクセスするとき、

a_type ob[10];
a_type *p = ob;
これは問題ないのに、

a_type ob[2][5];
a_type *p = ob;
これはエラーが出るのは何故?
684デフォルトの名無しさん:2006/02/07(火) 21:45:50
a_type**だから。
685デフォルトの名無しさん:2006/02/07(火) 21:47:13
a_type (*p)[5]=ob;
686デフォルトの名無しさん:2006/02/07(火) 22:07:50
684も未だにポインタが判らない人。
687デフォルトの名無しさん:2006/02/07(火) 22:23:25
>686
ほんとだ。すまんな、どうも気が触れていたようだ。
これで勘弁してくれ。つvoid*
688デフォルトの名無しさん:2006/02/07(火) 23:06:40
template<class T, int n>
class X
{
}

ここ int n の所を自分のオブジェクトにしたらコンパイルエラーが出るんだけどなんで?

template<class T, Point n>

みたいな感じで書くと

error: 'class Point' is not a vlid type for a template constant parameter

ってでちゃう。

689デフォルトの名無しさん:2006/02/07(火) 23:09:26
intじゃないから……

それは型じゃなくて値
690688:2006/02/07(火) 23:13:19
>>689
ありがとう。
int 型の値 n が渡せて何で Point 型の値 n が渡せないの?
691デフォルトの名無しさん:2006/02/07(火) 23:15:31
規格票くらい自分で何とかしろ
タダで閲覧できるところまである
692デフォルトの名無しさん:2006/02/07(火) 23:24:34
>690
そういう規格としか。
intとかboolとかの整数系はOKだけど、floatとか構造体とかアウト。
ポインタはどうだっけ?
693デフォルトの名無しさん:2006/02/07(火) 23:26:23
>>690
リンカに Point 型の値を処理させるのは、とても大変で、
任意のユーザー定義型まで考えるとほとんど不可能だから。
694デフォルトの名無しさん:2006/02/07(火) 23:32:07
リンカとかは後付け設定だな
そもそも 688 の意図が単にコンパイラを困らせるだけのように見える

# 後付け設定の権化が規格だったりもするが
695デフォルトの名無しさん:2006/02/07(火) 23:33:12
696688:2006/02/07(火) 23:38:41
>>692,693
ありがとう。駄目なんだね。
組み込みの整数型だけは渡せるようなナゾ仕様になってしまったのかはわからんが。

便利じゃね?

Point p1, p2;
length = getLength<float, p1,p2>();

とか書けたら。



それにしてもtemplateを勉強するのに良い本はない。
697デフォルトの名無しさん:2006/02/07(火) 23:47:41
>>696
それは
template <typename T> float getLength(T t1, T t2) {
return t2 - t1;
}
こうする事で int t = getLength<int>(5,8); などと書けるので
Point型に対した処理がしたいなら特殊化したテンプレートを書けば良いと思います
698デフォルトの名無しさん:2006/02/07(火) 23:54:20
>>697
それだと実行時の関数になる。
699デフォルトの名無しさん:2006/02/07(火) 23:55:04
つーかユーザー定義型の使用を認めたらただでさえ難解なtemplateが
可読性0の埋め込み型スクリプト言語になっちまうぞ。
700デフォルトの名無しさん:2006/02/07(火) 23:55:04
template<class T, Point& n>
template<class T, Point* n>
これならいける。
701デフォルトの名無しさん:2006/02/08(水) 00:01:38
>>698
最適化されるでしょう
702デフォルトの名無しさん:2006/02/08(水) 00:08:21
>>695
サンクス
703デフォルトの名無しさん:2006/02/08(水) 00:48:14
>>701
最適化されたとしても引数が定数でないことに変わりはないから、他のテンプレートに渡したりはできないわな。
>>696が何をやろうとしているのか分からんが。
704デフォルトの名無しさん:2006/02/08(水) 01:07:16
template< typename Key, typename Value >
void foo( map<Key, Value>& in )
{
    map<Key , Value>::iterator it;
}

これをコンパイルするとエラーになるんですが、
正しくはどう書けばいいんでしょうか?
705デフォルトの名無しさん:2006/02/08(水) 01:11:43
GCC だと

typename map<Key, Value>::iterator it;

とする必要がある。
でも、コンパイラによっては typename を入れた方がエラーになる。

#if defined(__GNUC__)
#define TYPENAME typename
#else
#define TYPENAME
#endif

とかやっといて、

TYPENAME map<Key, Value>::iterator it;

とするが吉。
706デフォルトの名無しさん:2006/02/08(水) 01:20:34
>>705
まさにgccでした。ありがとうございます。
707デフォルトの名無しさん:2006/02/08(水) 01:36:31
>>705
これって、規格的には typename 入れるのと入れないのと、
どっちの方が正しいのかな?
何か時代によって変わってそうな気もするけど。
708デフォルトの名無しさん:2006/02/08(水) 02:18:09
>>707
文句なく入れるのが正しい。
709デフォルトの名無しさん:2006/02/08(水) 02:18:38
mapが特殊化されていてiteratorは定義されていなかったりする可能性があるから
710デフォルトの名無しさん:2006/02/08(水) 02:53:48
なるほど。
「typename はテンプレート仮引数にしか使えません」
とかエラー出るコンパイラは、まだ準拠できてないってことか。
711デフォルトの名無しさん:2006/02/08(水) 03:17:52
typenameって、「これは型名ですよ」とコンパイラに教える意味も
持ってるんじゃなかった?
(classの先行宣言と一緒=以前はclassで代用してたのかも)

とすれば、>>704の例だと
typename map<Key , Value>::iterator; // 先行宣言
map<Key , Value>::iterator it;
なら、どんなコンパイラでも(typenameというキーワードをサポートしていれば)
通りそうな気がするんだけど。

試してないけどね。
712デフォルトの名無しさん:2006/02/08(水) 03:20:11
あ、でも、エラーが>>710だとしたら、絶対無理か。
713デフォルトの名無しさん:2006/02/08(水) 04:07:37
>>711
それはまったくのガセネタだな。どこで仕入れてきたんだ?
714デフォルトの名無しさん:2006/02/08(水) 04:09:59
>>713
ぐぐったら
http://ja.wikipedia.org/wiki/%E4%BA%88%E7%B4%84%E8%AA%9E_(C++)
のtypenameのところにあった
715デフォルトの名無しさん:2006/02/08(水) 04:21:20
>>714
は?そこの解説には >711 のような内容は書いてないぞ。
typename が宣言を作るわけじゃない。
716デフォルトの名無しさん:2006/02/08(水) 05:57:53
711の上の部分しか読んでなかった。

typenameが
1.テンプレート引数で型を引数にとることを示すことに使う。(classで代用可能)
2.続く識別子が型名であることを示す。
だから型名であることを言うだけで宣言じゃないのは確かだな
717デフォルトの名無しさん:2006/02/08(水) 08:37:34
delete について質問です。
new hoge[n] で獲得した領域は delete[] で解放しなくてはいけないそうですが、new hoge で獲得した領域を delete[] しても大丈夫でしょうか?
それとも delete[] したいなら、new hoge[1] とかするべきでしょうか(これだとコンストラクタに引数を渡したい場合に困りそうですが)。

あと、都合により
void *p = (void*)new hoge;
と獲得した領域を delete する場合、delete (hoge*)p とやらないと hoge のデストラクタが走らないのは仕様なんですよね?
つまり、delete に渡すポインタは、new したときの型で渡さないといけないということですよね?
# できればキャストせずにうまく動いて欲しいのですが
718デフォルトの名無しさん:2006/02/08(水) 08:59:06
new-deleteとnew[]-delete[]の対応は神聖不可侵。犯すべからず。

あとvoid*ではdeleteできません。 どのデストラクタ呼んでいいのか判らんでしょう。
// 技術的な可能不可能の話で言えば、vtbl持ってるクラスのインスタンスならvoid*でもdeleteできそうだけど、
// void*ポインタからvtbl持ってるか判別はできないのでやっぱり無理。
719デフォルトの名無しさん:2006/02/08(水) 09:07:01
強制的なポインタのキャストはやらない方がいいよね、安全面から。
ってそれを言語使用として禁止してしまわないのがC++のいいところ何だが。

なんでそんなことをしたいのか分からないけど、
もしいろんな型のオブジェクトを一手に扱いたい、なんてことであれば
一つの基底クラスから全部派生させるようにして
仮想デストラクタを使うようにするのがオブジェクト指向的だと思われ。
まぁ Java でいうところの Object クラスみたいなもん。
(C# だとどうなんだったっけ?)
720717:2006/02/08(水) 09:24:48
>>718
わかった。ありがとう。

でも、void* の delete の話を技術的に解決する話なら、new したときに獲得メモリブロックのヘッダにデストラクタのポインタか
vtblのオフセットかを記録しておけば、delete に渡されたときの型によらず適切なデストラクタを呼び出すことができそうじゃない?
いや、そういう仕様になってないんだから文句も無いけど。

>>719
char[] を獲得して void* に代入して、そのまま delete してるソースがあったから、気になって聞いてみた。
規定クラスの話は、自分で新規に作るなら多分そうします。
ありがとう。
721仕様書無しさん:2006/02/08(水) 11:25:41
全てのオブジェクト派生元となる基底クラスに ...

virtual void Suicide() { delete this; }

ってな仮想関数を用意して、

pObj->Suicide();

とでもすれば?
722デフォルトの名無しさん:2006/02/08(水) 11:29:12
>>721
それ、 virtual デストラクタ+普通の delete に比べて、何がメリットなの?
723デフォルトの名無しさん:2006/02/08(水) 11:39:48
>>721 仮想デストラクタじゃだめなの??
って書こうと思ったらすでに書かれてた。
724デフォルトの名無しさん:2006/02/08(水) 13:42:30
はじめまして
本日からC++をはじめた。初心者PGです。
さっそくお伺いしたいのですが。
javaで書く

data.java
----------------------
1|class data {
2|
3| public string data;
4| public string data2;
5|}
===================================
test.java
----------------------
1|import data;
2|
3|class test {
4|
5| MethodTest(data pData) {
6|
7| string strPara;
8| strPara = pData.data2;
9| }
10|}

はどのようにC++でどのように表現すればいいのでしょうか?

現在、C++でDLLを生成し VBで生成したDLLを使用する処理を作っているのですが。

DLLの呼び出し関数の引数と戻り値に 構造体を使用したいのです。
よろしくお願いします。
725デフォルトの名無しさん:2006/02/08(水) 13:51:11
こういうのがプロなのか
ネットを何だと思ってるのかな
726デフォルトの名無しさん:2006/02/08(水) 17:05:04
これは釣りだろ
727デフォルトの名無しさん:2006/02/08(水) 17:21:54
int i;
std::cin >> i ;
として数値を読み込んでいます。
もし入力されたモノが数値としてふさわしくない文字列だった場合、
そのことを知るにはどういう方法があるのでしょうか?
728デフォルトの名無しさん:2006/02/08(水) 17:22:58
if(!(std::cin>>i)){
    ふさわしくない時
}
729デフォルトの名無しさん:2006/02/08(水) 17:27:53
730デフォルトの名無しさん:2006/02/08(水) 17:41:12
>>728 ありがとうございます。
つまり、istream::fail() ということですね。
731デフォルトの名無しさん:2006/02/08(水) 19:26:34
>>720
メモリ空間を圧迫するから採用されなかったんじゃないかな。
たとえば、メンバがポインタ変数一つしかないようなクラスを考えると
デストラクタのポインタが増えることで実質倍のメモリを消費する。
732デフォルトの名無しさん:2006/02/08(水) 19:44:25
そもそも、そういうことはポリモーフィズムで解決するのが C++ 流。
そういう場合に void* を使った時点で設計ミス扱いされても文句は言えない。
733デフォルトの名無しさん:2006/02/08(水) 20:39:42
>>731
でもnewで割当てられたメモリブロックには元々メモリ管理情報が付加されてるから、ポインタ一つくらい増えても問題はないんじゃないかと思わなくも無い。
この辺は処理系依存と呼ばれる部分だろうけど。
734デフォルトの名無しさん:2006/02/08(水) 21:51:15
>>720
やろうと思えば、その通りのことがユーザコーディングでできてしまうのが C++ 。
735デフォルトの名無しさん:2006/02/08(水) 21:52:52
>>717
newして得たポインタを保持するのにboost::shared_ptr<void>を使えばよい。
boost::shared_ptrは自身のコンストラクタへの引数に与えられた型を保存しておいて、
その型でdeleteを呼んでくれるから、元の型のデストラクタが呼ばれる。
736デフォルトの名無しさん:2006/02/08(水) 22:02:47
初心者的な質問でもうしわけないですが
構造体をファイルで管理するのはどうすればいいのですか?
構造体のメンバも一つずつファイルに書きこまにと駄目なですか??
構造体名だけを保存してたんですが、いざメンバを使おうとしたら
読み込んでも使えない・・・・・・なにかヒントくださいTT
737デフォルトの名無しさん:2006/02/08(水) 22:04:34
構造体名だけを保存の意味がわからん。プログラミング言語であらわせ
738デフォルトの名無しさん:2006/02/08(水) 22:15:26
>>736
なにベースでコード書いてる?
Win32API? Cの標準関数? C++のストリーム系?
739デフォルトの名無しさん:2006/02/08(水) 22:22:43
Boost.Serializationなんて言ってみる。
740デフォルトの名無しさん:2006/02/08(水) 22:29:43
>>736
構造体を new するとき、ファイルを open
構造体からメンバを get するとき、ファイルから read
構造体にメンバを set するとき、ファイルから write
構造体を delete するとき、ファイルを close
する関数を作れば ok
741デフォルトの名無しさん:2006/02/08(水) 23:19:50
const参照についてなんですが、

class foo {
 T hoge_;
public:
 const T& hoge1; // <--(a)
 T const& hoge2; // <--(b)

 foo(): hoge1(hoge_),hoge2(hoge_) {}
};

上の(a)と(b)の書き方で何か意味の違いがあるのでしょうか?
742デフォルトの名無しさん:2006/02/08(水) 23:22:14
>> 741
ない。
743デフォルトの名無しさん:2006/02/08(水) 23:23:21
>>742
ありがとうございます。
744デフォルトの名無しさん:2006/02/08(水) 23:35:00
& const
の意味が聞きたかったんちゃうのか?
745デフォルトの名無しさん:2006/02/08(水) 23:36:40
& constなどない。
746デフォルトの名無しさん:2006/02/09(木) 00:05:57
質問です。
java では引数とメンバ変数がかぶっていても、メンバ変数の方を
"this.foo"とするようにしておけば特に問題ない。
1.C++ でも this ポインタを使えば同じことができるでしょうか?
(g++ では問題なかった)
2.(上がOKの場合のみ) C++ で this->hoge = foo; って書くと変?
747746:2006/02/09(木) 00:09:55
> 2.(上がOKの場合のみ) C++ で this->hoge = foo; って書くと変?

2.(上がOKの場合のみ) C++ で this->foo = foo; って書くと変?

の間違いでした…
748デフォルトの名無しさん:2006/02/09(木) 00:15:12
>>746
普通に出来るし変でもない。
749デフォルトの名無しさん:2006/02/09(木) 01:18:44
>>746
1.できるお
2.変じゃないお
750デフォルトの名無しさん:2006/02/09(木) 01:20:23
でも、そんなことをするのは馬鹿しかいない。
751746:2006/02/09(木) 01:55:41
ありがとうございます>>748-750
メンバ変数の方の頭や後ろに _ をつけたり m_ をつけて
this をはずせば馬鹿じゃないんでしょうか >>750
752デフォルトの名無しさん:2006/02/09(木) 02:09:26
>>751
名前が被ること自体が問題。
あえてリスクを負うようなコーディングスタイルは避けるのが
普通以上のレベルのプログラマの常識。

ただ、例外として問題が少々あろうが後腐れの無いプログラムで
そーゆー類のことをするのは全然構わんと思う。・・・逆にそーゆー
融通が利かすことができないのは一流気取りの三流プログラマ。
753デフォルトの名無しさん:2006/02/09(木) 02:34:30
>>752
名前が本質的に同じであるのが自然である場合、
あなたは、どういう醜い名前の付け方をするんですか?

class date{
    int year;
    ........
public:
    ........
    void set_year(int year){
        this->year = year;
    }
};
754デフォルトの名無しさん:2006/02/09(木) 02:38:54
>>752
setterでは普通に使ってるけど、やめた方がいいんだろうか…
void setHoge(type hoge) {this->hoge = hoge;}
755デフォルトの名無しさん:2006/02/09(木) 02:41:06
>>753
g_ だの m_ だのといったプレフィックスを見たこともない人ですか?

自分のスタイルを押し付けるような気は毛頭ないがなんらかの方法で
名前が完全に被るようなことは極力避けるのが普通だぞ。
756デフォルトの名無しさん:2006/02/09(木) 02:43:28
>>754
俺はそのケースでも引数にプリフィックスを付けて
名前の重複を避けるようにしてるけど
このケースは許容範囲なんじゃない?
757デフォルトの名無しさん:2006/02/09(木) 02:58:01
てか、よくよく考えたらプレフィックス付けるほうが this-> を
使わなくても済むから結果的に表記もすっきりするね。

void setHoge(type hoge) {this->hoge = hoge;}

void setHoge(type a_hoge) {hoge = a_hoge;}
758753:2006/02/09(木) 03:07:56
>>755
えーと、変数に無駄な接頭語付ける文化ってまだ存在してたんですね。
自分の場合ハンガリアンが駄目絶対と言われてたのを、
目にしてたので死滅したものかと思っていました。

個人的には、グローバル変数はg_hoge,メンバ変数はm_hogeとかするくらいなら
::hoge,this->hogeと書けば、
言語レベルでそのスコープにアクセスしていると保障が得られるので
素直に言語の機能を使ってました。

なのでスコープを明示的に指定できるC++で、
変数名にスコープ情報を入れたり無駄な接頭語を付けるのは、
気持ち悪いし美しくないなぁ、と思っています。
759デフォルトの名無しさん:2006/02/09(木) 03:32:42
必要に応じて this-> 付ける場合、
this-> 忘れるバグを埋め込む可能性を恐れるよりは、
m_ つけた方がよっぽどいい。
明らかに異なる名前なら、間違える可能性がグンと減る。
毎回 this-> つけるなら別だが、長ったらしい。
760デフォルトの名無しさん:2006/02/09(木) 03:48:41
>>758
「プリフィックス」と「ハンガリアン」を混同してる人ってまだ存在してたんですね。
MSもハンガリアンを推奨しなくなったんで死滅したものかと思っていました。

個人的には、所謂 getter に名詞を使うので、メンバ変数に m_ つけないと
被ってどうしようもなくなります。この衝突は this-> とかじゃ逃げれませんし。
761754:2006/02/09(木) 04:00:12
>>757
引数にプリフィクスを付ける手もあるのか、なるほど。
自分はメンバ変数をhoge_としています。

>>759
個人的には
void setHoge(type hoge) {this->hoge = hoge;}
は見やすくて好きなんだが、
バグのとこを考えると避けた方がいいように思えてきた。
762753:2006/02/09(木) 04:03:31
>>760
変な接頭語付ける文化は興味が無くて、
その手の文化はハンガリアンしか聞いたことが無いので勘違いしておりました。

確かにメソッドと変数名の衝突は頭が痛くなる問題ですね。
自分の場合getterにはget_hogeのような2単語で構成するのが殆どなので、
変数とメソッドの衝突は未経験ですが、
それを考慮すると奇妙な名前を付けるのも仕方がないのでしょうね。

今まで奇妙な接頭語を付ける人の気持ちを理解できなかったのですが、
理解はできました。

ありがとうございます。
763デフォルトの名無しさん:2006/02/09(木) 04:13:56
Ruby の @ を付ければメンバ変数という仕様が
C++ でも欲しくなってくるなぁ。
764デフォルトの名無しさん:2006/02/09(木) 04:31:07
#define @ this->
無理か
765デフォルトの名無しさん:2006/02/09(木) 04:41:36
せめてthisが参照になればなあ
operator[]とかポインタじゃ呼び出しにくい
766デフォルトの名無しさん:2006/02/09(木) 04:45:58
this[0]["hoge"]
767デフォルトの名無しさん:2006/02/09(木) 05:28:06
>>763
個人的に、そういう仕様はあまり好きになれない。
768デフォルトの名無しさん:2006/02/09(木) 06:22:22
>>745
コンパイラが新しければね
769 ◆Uy3UpqU1oc :2006/02/09(木) 07:11:41
初めて書き込みますが相談があります。m(__)m
書き込みや読み込み先のファイルの、場所の指定はできないんですかね?
770デフォルトの名無しさん:2006/02/09(木) 07:32:37
朝から釣りかよ
771デフォルトの名無しさん:2006/02/09(木) 07:40:47
>>765
C++にthisが入ったのが、参照が入ったのより前だからごめん、
って禿がゆってた。
772 ◆Uy3UpqU1oc :2006/02/09(木) 07:50:18
釣りではないんですが…orz
773デフォルトの名無しさん:2006/02/09(木) 08:22:28
キリンさんの首輪はどこに付けたらいいの?
774デフォルトの名無しさん:2006/02/09(木) 09:20:31
標準ストリームで、整数を 1234567 という形式ではなく
1,234,567 という形式で出力させる事はできますか?
775デフォルトの名無しさん:2006/02/09(木) 09:45:48
適切なlocaleを与えれば可能。例としてVC++7.1で。

locale loc("jpn");
cout.imbue(loc);
cout << 1234567 << endl;
776 ◆Uy3UpqU1oc :2006/02/09(木) 10:23:30
すみませんでしたm(__;)m
自分であっちこっち移動させました…
777デフォルトの名無しさん:2006/02/09(木) 12:52:30
Cの時の癖でそのまんまハンガリアンしてる俺って
就職したら迫害されるんだろうか
778デフォルトの名無しさん:2006/02/09(木) 16:25:15
>>777
コーディング既約で一応変数名についてはそれなりの基準を示すから
現場では適宜それにしたがってくれればいいよ.
779デフォルトの名無しさん:2006/02/09(木) 16:30:19
>>769
Windowsユーザと邪推すると、ディレクトリ記号「\」はエスケープシーケンスで使われるので

ifstream fin("C:\\Documents and Settings\\Gates\\testament.txt");

というように「\\」と重ねなければならない。

もしこれで正答なら漏れエスパー。
780デフォルトの名無しさん:2006/02/09(木) 16:44:19
識別子 : 英字はすべて小文字、単語の区切りは下線
メンバ変数 : 下線を最初につける
引数 : 下線を最後につける、主となる引数を下線だけにする
getter : 素の名前
setter : set_を最初につける

↓こんな感じ
class X {
 int _width;

public:
 X(const int& width_) : _width(width_) {}
 int width() const { return _width; }
 int set_width(const int& _) { return _width = _; }
};
781デフォルトの名無しさん:2006/02/09(木) 16:51:27
>>780
先頭の文字がアンダーバーなのは、
C++の処理系に大域名として予約されているから余り好きじゃないなぁ。
大域名にマクロ使われるかもしれんし。
782デフォルトの名無しさん:2006/02/09(木) 16:52:19
>>774
template <typename T>
inline std::string number_format(const T& target_, std::size_t w_=3, const std::string& s_=",") {
 std::string n = xtos(target_);
 std::size_t p = n.find('.');
 if (p == std::string::npos) p = n.size();
 while ((p -= w_) > 0) n.insert(p, s_);
 return n;
}

xtos()は次の通りだけれど、Boostのlexical_castを使った方がいいと思う。

template <typename T>
inline std::string xtos(const T& _) {
 std::string s;
 std::stringstream ss;
 ss << _; ss >> s;
 return s;
}
783デフォルトの名無しさん:2006/02/09(木) 17:20:04
>>780
ルールを覚えるのが面倒だから面罵も下駄も雪駄も同じ名前でいいよ。
class X {
 int width;

public:
 X(const int& width) : width(width) {}
 int width() const { return width; }
 void width(const int& _) {width = _;}
};
784デフォルトの名無しさん:2006/02/09(木) 17:39:58
俺はm_派。アンダーバー一つだと普通に間違えそうで怖い
あとgetterが素の名前()ってのはSTLでも使われてるけど
パブリック変数なのかゲッター関数なのか紛らわしくないか?
STLとか自分で書いたライブラリならまず間違えないし
間違えたとしてもコンパイルエラーで済むって言われたらそれまでだが
785デフォルトの名無しさん:2006/02/09(木) 18:01:28
>>784
パブリック変数を使わず、必ずgetterを書くようにすることで統一を。
コンパイラが最適化のチャンスを見逃したら悲惨なことになるけどw

型名を接頭子にするのはどうしても慣れないなあ。
std::map<std::string, std::vector<std::pair<std::string, std::string> > >** p;
とかってハンガリアン記法で書くとどう書くの?
786デフォルトの名無しさん:2006/02/09(木) 18:36:26
omanko
787デフォルトの名無しさん:2006/02/09(木) 18:43:09
可能な限り、標準に近い形でライブラリは記述
クラスメンバには、Prefix、Suffix などはつけない方向で。
メンバ変数が埋もれそうな状況になったら、
ヘルパクラスや関数にする。

それ以外は、C++ Coding Standards を参考にする。

template< typename TypeName >
class class_name
{
public:

 typedef TypeName type;

 enum enum_name { item_name };
 
 // 下駄。標準 stream などに見られる形式
 type value() const { return val; }

 // 雪駄。標準 stream などに見られる形式
 type value( type const & newval ) { val = newval; }

private:

 // 略名. prefix, suffix なし
type val;
 
};
788デフォルトの名無しさん:2006/02/09(木) 18:49:32
M$製のSDKのサンプルみたいなm_pNextFrame
みたいな長くて堅苦しいのが好きだから
STLのコードが読みにくくてしょうがない
789デフォルトの名無しさん:2006/02/09(木) 18:50:16
みたいなが連続した俺文盲
790デフォルトの名無しさん:2006/02/09(木) 21:48:38
C++0xには@文字列付かんの?
@"c:\Documents and Settings\Gates\testament.txt");

みたいなC#モドキにしてくれぇ。
791デフォルトの名無しさん:2006/02/09(木) 22:03:15
>>790
Windowsは意外と大抵/を受け付けてくれるよ。
たまに\しか受け付けないものもあるけど。
792デフォルトの名無しさん:2006/02/09(木) 22:19:30
>>791
dクス。UNIXがセパレータに'/'を使っていたので、ビル・ゲイツがひねくれて
わざとバック・スラッシュ文字を使ったような事は聞いた事があるけど、'/'も
使える場合があるのか。試してみる。
793デフォルトの名無しさん:2006/02/09(木) 22:33:46
>>792
いや、単にCP/Mが/をコマンドラインスイッチに使用してたんで互換性の都合上/が使えなかっただけらしいが。
794デフォルトの名無しさん:2006/02/10(金) 14:22:51
>793
そうだね
MS-DOS = (CP/M + UNIX) / 3
だから
795デフォルトの名無しさん:2006/02/10(金) 20:25:17
/3 テラワロス
796デフォルトの名無しさん:2006/02/10(金) 20:41:16
俺の感覚だと
MS-DOS = CP/M + UNIX / 10
くらいだな
797デフォルトの名無しさん:2006/02/10(金) 21:33:52
DLLを修正してビルドすると.libも再作成されますが、
インタフェースを変更していない場合、参照している
呼び出し元プログラムはリビルドする必要があるので
しょうか?
皆さんはリビルドしていますか?
798デフォルトの名無しさん:2006/02/10(金) 22:03:14
リビルドが必要なら、それはインターフェイスではない
799デフォルトの名無しさん:2006/02/10(金) 23:06:50
>>797
処理系によるかと
昔のHPだと、たま〜〜に再リンクが必要だった
800デフォルトの名無しさん:2006/02/10(金) 23:10:13
自分も、m_・・は好きになれない
美しくない・汚い・見るに耐えない
(慣れの問題だとは思うが・・)

抽象化が進むと、変数名命・メソッド名命
に、なって来るから余計そう思う
801デフォルトの名無しさん:2006/02/10(金) 23:23:35
>>800
引数に対する a_ もダメか?
argument の頭文字で a なわけだけど
そのまま前置詞の a と見なすことできるから
全然汚くないと思うんだが。

あと、お前が後半で言ってることの意味が不明。
802デフォルトの名無しさん:2006/02/10(金) 23:35:39
>>800
while(true) {
何でそんなに気にするのかよくわからん

private メンバは関数で言うなら auto 変数のようなもので
外から名指しされることのない、いわば自己責任の範疇だし

ちょっと込み入った処理をする場合はいちいち this-> ではアクセスせず
auto にキャッシュして最後に代入するだけだ
}
803デフォルトの名無しさん:2006/02/10(金) 23:42:17
>>801
引数・ローカル変数に「a」を付けるのは綺麗&今、マイブーム
(勝手な感覚だけど)
val=aVal;
何となく良い
引数とローカル変数の区別を、どう付けるべきか思案中
(区別するまでも無いとの説アリ)

後半はoo限定の話でした
804デフォルトの名無しさん:2006/02/11(土) 00:24:26
>>802
>何でそんなに気にするのかよくわからん
単なる(?)感覚的な問題

>private メンバは関数で言うなら auto 変数のようなもので
これは、全然違う希ガス
805デフォルトの名無しさん:2006/02/11(土) 00:43:47
メンバ変数は関数で言うならグローバル変数のようなもの。
クラスのどこからでもアクセスできて、
メンバ関数を抜けても値が保存される。
806デフォルトの名無しさん:2006/02/11(土) 00:50:34
>>805
>>802はprivateメンバ「関数」の話をしてるんだと思う。
807デフォルトの名無しさん:2006/02/11(土) 00:55:00
m_が汚く見えるのは多分_Tyとかかなり短く略した命名してる人だろうな。
808デフォルトの名無しさん:2006/02/11(土) 01:22:23
>>806
privateとpublicは、今の話には関係無い

>>807
長い変数名に、m_付ける方が汚く見える気がする
それ自体で意味成しているのに
それに余分な、m_付けるのはかなり気になる
809デフォルトの名無しさん:2006/02/11(土) 01:52:50
最近のマイブームは
int member();
void member( int value );
int member_;
しかしスレ違いな気が……
810デフォルトの名無しさん:2006/02/11(土) 02:06:33
>>808
>privateとpublicは、今の話には関係無い
privateメンバ変数の名前はインターフェースに含まれないから、
適当に名前を割り当てても良い、というのが>>802の意見だろ。
811デフォルトの名無しさん:2006/02/11(土) 02:31:35
>>809
メンバ変数の最後に「_」付けるのは、目立たなくて控えめで個人的には好き

>>810
なるほど・・・そう言う意味ならば、>>802は、余計拙いと思う
メンバ変数は、>>805も言っている通り、グローバル変数的意味合いが強くなりやすい
(「1クラス=1責務」の原則を知らない人が多い現状では尚更)
ので・・・
ってか、public変数使う機会って、ほとんど無い・・と思う
少なくとも自分は1年以上使ったこと無い
812デフォルトの名無しさん:2006/02/11(土) 02:43:40
命名規約の話は
どうせ最終的にはどちらも譲らなくて宗教戦争になるだけなんだから
出来れば他のスレでやって欲しいんだけどな。

http://pc8.2ch.net/test/read.cgi/tech/1068752664/
とか。
813デフォルトの名無しさん:2006/02/11(土) 02:56:28
単に勝手に好きな事言い合ってるだけだから良いんでないかい?
変数名・関数名の選定って、一番重要って説もあるくらいだし。
814デフォルトの名無しさん:2006/02/11(土) 03:08:41
と、当事者は申しております
815デフォルトの名無しさん:2006/02/11(土) 06:35:14
>メンバ変数は、>>805も言っている通り、グローバル変数的意味合いが強くなりやすい

おいおい、1クラス=1責務とか言ってる尻から何を血迷ったことを?

メンバ変数にするか関数内ローカル変数にするかは、
それぞれ合理的な理由でスコープを選択するわけで
グローバル変数にさえそれは当てはまるだろうがよ

昔の BASIC や COBOL のグローバル変数と一緒にしとるんちゃうか?
816デフォルトの名無しさん:2006/02/11(土) 08:57:48
クラスのメソッドを関数ポインタみたいに出来ないでしょうか
具体的には、コンストラクタでメソッドの飛び先を変更して、
クラスの実行先ではそれを意識しないですむというものです

class hoge {
public:
void print();
 void print_a();
void print_b();

 hoge(int num) {
  // ここでprintメソッドの実行先をprint_aまたはprint_bに変更
}

};

hoge h(1), hh(2);
h.print(); // print_aが実行される
hh.print(); // print_bが実行される
817デフォルトの名無しさん:2006/02/11(土) 09:00:23
1. 継承でなんとかする設計にする
2. メンバ関数ポインタ(void (hoge::*)())を使う

どっちにするかは状況次第。
818デフォルトの名無しさん:2006/02/11(土) 09:25:53
templateってのもあるな。
819デフォルトの名無しさん:2006/02/11(土) 10:16:17
それで解決できる状況なら、
普通にオーバーロードで解決できるんじゃ・・・。
820デフォルトの名無しさん:2006/02/11(土) 11:11:57
>>816
hとhhが同じ型でなくてよいならtemplateで解決(MC++D参照)
同じ型ならば>>817の案をセレクト。
821デフォルトの名無しさん:2006/02/11(土) 11:19:05
switch-caseで分岐する方法が……
822デフォルトの名無しさん:2006/02/11(土) 11:27:23

  / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
  | switch-caseで分岐って聞こえたような気がする!!
  \_______  ____________
              ∨
    |
    |
   / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
  /          ____   
/            | 19:00 |  
              ̄ ̄ ̄
               _______
              /    _   /  ,__  
            ∧∧ガバッ!  () /    iii■
           ( ;゚Д゚)ミ    ̄/      
         /\∪ ∪ ̄\/ ∫∫
        / ※⌒⌒⌒⌒/  ∫∫    
      / ※※※※ /  ⊂⊃
     / ※※※※ /   ┗━┛ 
    (______,,ノ        
823デフォルトの名無しさん:2006/02/11(土) 11:32:37
何!switch - case だと!!
824デフォルトの名無しさん:2006/02/11(土) 11:38:19
こうしちゃおれん
825デフォルトの名無しさん:2006/02/11(土) 12:13:24
別に本当にswitch-caseでも問題ない気が
826デフォルトの名無しさん:2006/02/11(土) 13:16:29
>>825
何らかの理由で出来ないのでしょう。
hogeのコンストラクタで関数をチョイスしていることから推測
827デフォルトの名無しさん:2006/02/11(土) 14:40:23
class A
{
private:

public:

};

と書いています。しかし先輩から、お前のは見にくいから止めろと言われました。

class A
{
public:

private:

}

どっちが普通なんですか?
828デフォルトの名無しさん:2006/02/11(土) 14:49:30
>>827
プログラムに限らずテキストを書くときには
人に見てもらいたいところを先に書いたほうがいい、
というのはわかる?

「これは基本的にあなたは知らなくてもいいんですが
 ・・・
 ・・・
 おっとここまで書いたところは気にしないで下さいね。
 いつ内容が変更されるかわかりませんよ。
 さて、結局のところは
 ・・・
 ・・・。」
こんな文章読まされたら嫌だと思わない?
829デフォルトの名無しさん:2006/02/11(土) 14:49:35
どっちでも良い。
単なる糞くだらない宗教問題だから気にするな。

ただ、もしコーディング規約とかで、
定められているのならそちらを使えばいい。

規約が無いのなら自分で良いと思うほうを使えばいい
830デフォルトの名無しさん:2006/02/11(土) 14:53:17
>>828
ok。すべて書き直すぜ☆
831デフォルトの名無しさん:2006/02/11(土) 15:24:07
立場によってprivateとpublicどっちをよく見るかは変わるだろ
まぁそれでもpublicが先のコードが多いけどな
832デフォルトの名無しさん:2006/02/11(土) 15:25:34
>>828
本当にメンバ変数を隠蔽したいならPimplを使うべき。
classには「何も指定されてないものはprivateである」という
明確な仕様があるから、それに従って

class A
{
ここにprivateなものを定義

public:
ここのpublicなものを定義
};

こう書いてるよ。

一番悪いのは、メンバ関数の定義とメンバ変数の定義が
ごっちゃになってたり、staticなメンバとそうでないのが
混ぜこぜになってたりすること。
833デフォルトの名無しさん:2006/02/11(土) 16:00:27
>>827
先輩がなんで見にくいのか俺にはわからん。
メンバ変数の宣言が上下どちらかに統一されて
メンバ変数の初期化の順序が守られていればどっちだっていいよ。

それよりもクラスに対しての適切なコメントがないのが嫌。
834デフォルトの名無しさん:2006/02/11(土) 16:26:34
>>832
pimpl にはオーバーヘッドとコードの増加が伴うので、
それが許容できる場面でなければ使えない。

class の暗黙の private を省略するのは、
演算子の優先順位に依存してカッコを省略するのと
同じぐらいウザイと思う。
明確な仕様というが、デフォルトで private になっている理由は
そんなに明らかではないだろう?
835デフォルトの名無しさん:2006/02/11(土) 16:27:23
このレベルの話だったら、一貫性やコメントのほうがずっと大切だと思う。
836デフォルトの名無しさん:2006/02/11(土) 16:32:32
>>834
「デフォルトではprivateである」という事実は十分一般的なんだから問題ないと思うが…
837816:2006/02/11(土) 16:33:16
ありがとうございます
メンバ関数ポインタを使用します
838デフォルトの名無しさん:2006/02/11(土) 16:33:16
>>834
>pimpl にはオーバーヘッドとコードの増加が伴うので、
>それが許容できる場面でなければ使えない。
許容できる場面の方が多いのでオイラはディフォルトはpimplにしてるな
最適化する段階でプロファイルしてクリティカルなものをメンバ変数にするようにしてる
839デフォルトの名無しさん:2006/02/11(土) 16:38:57
>>836
public:が先頭に来るスタイルも多いんだから
見間違える可能性は小さくないだろ
840デフォルトの名無しさん:2006/02/11(土) 16:39:36
>>836
演算子の優先順位に依存してカッコを省略する人ですか?
841デフォルトの名無しさん:2006/02/11(土) 16:44:16
コーディングスタイルとして規定されて統一されてればどっちでもいい
842デフォルトの名無しさん:2006/02/11(土) 16:44:24
>>840
依存せずに括弧を書く人ですか?
((((A+B)+C)+D)+E)
843デフォルトの名無しさん:2006/02/11(土) 16:45:17
全く、括弧を省略するとは信じられないな。
1つたりとも無駄な括弧などないのに。

(- (+ 1 (* 2 (+ 4 6)) (/ 4 2)) 2)
21
844デフォルトの名無しさん:2006/02/11(土) 16:46:01
MLで括弧を省略するとカッコいいな
845デフォルトの名無しさん:2006/02/11(土) 16:46:16
lisperは黙れw
# いや俺はlisp大好きよ
846デフォルトの名無しさん:2006/02/11(土) 16:49:53
みっともない
847デフォルトの名無しさん:2006/02/11(土) 16:50:17
>>842
その式は演算子の優先順位に依存していないから、
省略しても問題ないと言えるんじゃね?
848デフォルトの名無しさん:2006/02/11(土) 16:53:32
classの暗黙のprivateに期待するのが悪いのなら、
当然ながらstructの暗黙のpulicにも期待しないんだろうな?

struct Point
{
public:
  int x, y;
};

当然、わざわざpublicを書いてると。

限りなくウザス
まさか「structの暗黙のpublicだけは信じる」とか言わんよな?
849デフォルトの名無しさん:2006/02/11(土) 16:54:16
見間違えるかどうかは微妙だなぁ。
private:を省略するスタイルも一般的ではあるから見れば分かるし、
直後に連続して「public:」が続いていたら、不自然に感じるから問題はない気がする。
そもそも、メンバ変数をpublicにする状況というのも頻繁にあるわけじゃないしね。
850デフォルトの名無しさん:2006/02/11(土) 16:56:15
structは暗黙でpublic、classは暗黙でprivateって
明確に仕様で決まってるから、structとclassの違いに意味がある。

いちいち冗長なpublicやprivateを書く方がムダ。
851デフォルトの名無しさん:2006/02/11(土) 17:04:24
>デフォルトで private になっている理由は
>そんなに明らかではないだろう?

ARMにははっきり書いてあるし、仕様書は見てないが書いてあるだろう。
D&Eにも、C with Classesの最初期から「デフォルトはprivate」と
はっきり意識していたと書いてある。

Javaみたいな言語と違って、C++の場合は「sizeof(class)」が重要な
意味を持つから、クラスのサイズを規定するものは一番最初に
書いた方がいい。その方が絶対にバグを減らせる。
852デフォルトの名無しさん:2006/02/11(土) 17:06:38
ここまで話進んでるとは思わなかったよ、、、
今やっと半分ぐらい書き直したところ。
853デフォルトの名無しさん:2006/02/11(土) 17:13:16
宗教論争をしてる奴ってそれが意味のある議論だと信じて疑わないんだなホント
854デフォルトの名無しさん:2006/02/11(土) 17:16:18
>>828
pimplを使わない限り、classのprivate部分の変化は
そのclassを使っている全てのコードのリコンパイルを要求する。

Javaじゃないんだから「private部分はクラスのユーザーには無関係」
と言い切ることはできないのさ。

本当にprivateを意識させたくなければpimplを使うのが筋。

実装がFixしていてprivate部分に変化が無くなったら、
publicインターフェイスドキュメントを充実させればいい。
その方がよっぽど役に立つ。
855デフォルトの名無しさん:2006/02/11(土) 17:19:48
struct の暗黙の public は直感的。
この仕様によって C と互換性を保っていることが簡単に推測できる。
全部 private だったら friend つけない限り意味無いし。

class の暗黙の private は、この仕様に決めた理由を知らないし、
推測することができない。

俺が無知なだけ?
856828:2006/02/11(土) 17:22:13
>>854
そんなのは知ってるよ。
でも public を先に書いたほうが良いのに変わりは無いよ。
857デフォルトの名無しさん:2006/02/11(土) 17:22:40
>>855
お前が無知なだけ

classというキーワードを作ったそもそもの目的は、
「外部からのフィールドのアクセスが禁止されたstruct」
を作りたかったから。
858デフォルトの名無しさん:2006/02/11(土) 17:24:51
考古学乙
859デフォルトの名無しさん:2006/02/11(土) 17:25:26
>>856
俺はこんな感じにしてるけど。

class Foo
{
// プライベートなメンバ変数の定義

public:
// コンストラクタに始まるパブリックインターフェイス

protected:
// 派生クラスへのインターフェイス

private:
// プライベートなメンバ関数
};
860855:2006/02/11(土) 17:29:09
>>857
そんなのは知ってるよ。
でもこの仕様に決めた理由がわからないのに変わりは無いよ。
861デフォルトの名無しさん:2006/02/11(土) 17:30:39
>>860
そんなのは知ってるよ。 
でも お前が無知なのに変わりは無いよ。 
862デフォルトの名無しさん:2006/02/11(土) 17:38:14
>>861 なら理由を教えてやれよw
863デフォルトの名無しさん:2006/02/11(土) 17:39:09
C++で、クラスのprivateメンバ変数の数とかサイズとかが
真っ先に気にならない奴って、C++におけるコピーとか代入とか
STLコレクションの挙動とかを全く理解してないんだろうと推測できる。

privateメンバ変数が超巨大で、その下に書いてあるpublic部分が
画面外に追いやられるような状況なら、分割かpimplを真剣に検討すべき。
864デフォルトの名無しさん:2006/02/11(土) 17:40:41
>>862
>>857で十分だと思うが
865デフォルトの名無しさん:2006/02/11(土) 17:43:23
今北産業だがD&Eも読まずに話している連中が多いのはわかった。
866デフォルトの名無しさん:2006/02/11(土) 18:30:15
>863
あんたはSTLコンテナのイテレータが保持しているメンバ変数の数とかサイズとかを気にしているの?
867デフォルトの名無しさん:2006/02/11(土) 18:50:03
現場でルールとして決められたらそれに従う、これが守れりゃいいんだろ?
868デフォルトの名無しさん:2006/02/11(土) 18:56:20
sizeofが信用できないので自分で計算します。
869デフォルトの名無しさん:2006/02/11(土) 18:58:02
>>866
コピーのコストは気にするよ。
870デフォルトの名無しさん:2006/02/11(土) 18:58:38
ルールを決められる立場ならそれでいいが、
ルールを決める立場には問題が残る。
871デフォルトの名無しさん:2006/02/11(土) 19:00:58
>>869
だからって真っ先には気にならない。
クラス定義に現れる順番は public インターフェースの後ろでいい。
872デフォルトの名無しさん:2006/02/11(土) 19:09:36
内部の細かい仕様を覗き見させないで
知っとかないと問題のある事は仕様として公開するべきじゃないのか?

>>869の例なら内部に巨大なデータを保持していてコピーに時間がかかる事を
書いておくな俺だったら
873デフォルトの名無しさん:2006/02/11(土) 19:09:46
>>871
コンストラクタをprivateにしてSingletonや継承禁止にしたり、
コピーコンストラクタや代入演算子をprivateにしたりする事があるよな。

「明示的にprivateにしている」事もpublicインターフェイスを
構成している(コピーできない、構築できない、継承できない等)
場合があるが、お前はそれはどこに書くの?
874デフォルトの名無しさん:2006/02/11(土) 19:16:04
>>872
>内部の細かい仕様を覗き見させないで

それは要するにpimplで解決。

>知っとかないと問題のある事は仕様として公開するべきじゃないのか

C++の場合、例えprivateでも、メンバ変数のサイズは
「知っとかないと問題のある事」の1つだろ。

private関数は、ユーザーが知る必要は全くないけど。
875デフォルトの名無しさん:2006/02/11(土) 19:20:09
いや そのりくつは おかしい。
>>873はクラスを見たとき必ずprivateを真っ先に見るのか?
privateの中身が問題になる事があるって言っても
publicよりprivateのほうを良く見るって事にはならないだろ

>>874
ヘッダにクラス設計として実装されてることを公開って言ってるわけじゃない。
876871:2006/02/11(土) 19:25:07
>>873
コピー不可については自明なことも多いので
boost::noncopyable が使えればそれで。
使えなければ単純な private ブロックの直前に別で書く。

// noncopyable
private:
 例の奴ら

private:
 ...

その他、構築できない、継承できないなどは
クラスについてのコメントとしてクラス定義の直前に理由を添えて書く。
877デフォルトの名無しさん:2006/02/11(土) 19:31:14
>>874
private なメンバ変数のサイズをクラス定義を見て知ったとしても、
それに依存したコードを書くのはダメだろ。

問題が起こってから解決のためにサイズに依存した
回避コードを書くことはあるかもしれないが。
878デフォルトの名無しさん:2006/02/11(土) 19:40:19
ARMとかD&Eとかでは、classかstructかに関係なく、
メンバ変数は先頭にアクセス指定無しで書かれてる。

structならpublic、classならprivateとなる。
Bjarneとしては、classとstructの違いを活かして
メンバ変数は先頭にまとめて書け、って方針みたいだ。
879デフォルトの名無しさん:2006/02/11(土) 19:44:32
>>877
sizeof(class)に依存したコードなんて書く池沼がどこにいるの?
880デフォルトの名無しさん:2006/02/11(土) 19:48:24
>>878
ふむ、ってことは、
先頭にメンバ変数を書かないのは基本的にはマイナーな俺ルールなのか。
自分の書き方は先頭派で禿と同じで少し安心。
881デフォルトの名無しさん:2006/02/11(土) 19:50:59
>>879 さぁ? >874 あたりにいるんじゃないか?
882デフォルトの名無しさん:2006/02/11(土) 20:39:48
確か禿はユーザーが気になるのはpublicインターフェースだから
先にpublicを書けと言っていたはずだが

>>878
>>880
すごい自演を見た
883デフォルトの名無しさん:2006/02/11(土) 20:50:15
>>882
それはメンバ関数の話じゃないの?

禿げの本では、どれもメンバ変数は先頭に書いてるよ。
884デフォルトの名無しさん:2006/02/11(土) 20:53:37
>>883
public->privateの順で書くよりも
private->publicの順で書く方がprivateが短く書けるから
本ではそう書くようにしているとも言っている
885デフォルトの名無しさん:2006/02/11(土) 20:54:26
- privateが短く書けるから
+ privateをを省略出来て短く書けるから
886デフォルトの名無しさん:2006/02/11(土) 20:58:08
>>884
ソースキボンヌ
887デフォルトの名無しさん:2006/02/11(土) 20:59:11
>>886
確か禿本の最初の方だったと思う
888デフォルトの名無しさん:2006/02/11(土) 21:04:56
>>816
遅レスだが・・
print()をインターフェースで分離する・・に1票
889デフォルトの名無しさん:2006/02/11(土) 21:16:02
>privateをを省略出来て短く書けるから

いやちょっとその意見にはさすがに納得できない
890デフォルトの名無しさん:2006/02/11(土) 21:18:46
>>888
結局のところ、>>816をリファクタリングするのか、
>>816をそのまま実現するかで話は違ってくる。

>>816をそのまま実現するなら、print()の中でswitch〜caseするのが
一番素直な方法だと思うが。

typedef void (hoge::*hoge_print_t)();
static hoge_print_t hoge_print_table[] ={
  &hoge::print_a, &hoge::print_b
};

void hoge::print(){
  this->*(hoge_print_table[ m_num - 1 ])();
}

こんな方法もあるにはあるけど。
891デフォルトの名無しさん:2006/02/11(土) 21:27:25
>>889
書籍にコードを載せる際には、そういうのが結構あるんじゃないかと思う。
public:
とかだけで普通、一行食うし。
892デフォルトの名無しさん:2006/02/11(土) 21:30:40
>>890
>>816をそのまま実現すると巨大な一枚岩クラスの温床になりかねないので
そこから「改造」したいなあぁ・・って感じです

使い捨てAPLならば、switch〜caseに1票
893デフォルトの名無しさん:2006/02/11(土) 21:37:44
>>884
ヒント: 紙面の都合上
894デフォルトの名無しさん:2006/02/11(土) 21:46:05
「本ではこう書いてるけど実際のコードはどっちがいいのか知らん」
って意味か
895デフォルトの名無しさん:2006/02/11(土) 22:00:43
プロポーショナルフォントでソースコード印刷する人だからなぁ。
896デフォルトの名無しさん:2006/02/11(土) 22:28:19
public:やprivate;を書くか書かないでよくここまで盛り上がることが出来るな。
一秒のtypingをケチるような奴は関数名や変数名もろくでも無いものにしているのだろうな。
897デフォルトの名無しさん:2006/02/11(土) 22:28:34
delete this;

ってありですか?
898デフォルトの名無しさん:2006/02/11(土) 22:35:26
899デフォルトの名無しさん:2006/02/11(土) 22:38:57
>>897
できる。
もちろんそれ以降メンバ変数・関数を扱わないこと。
また、大抵の場合はnewで確保されたものでないとだめだろうから、それにも気を付けること。
900デフォルトの名無しさん:2006/02/11(土) 22:42:38
>>899
ありがとうございます。

できるんですね。
自己消滅できれば便利なのになーとか考えてたんですが、
delete thisについて書かれてるようなものが見つからなかったので,,,
901デフォルトの名無しさん:2006/02/11(土) 23:03:31
>>900
やめとけ、メンドクサイ。だいたい、ほんとで探したのか?すでに FAQ の一つだぞ。
ttp://www.tietew.jp/cppll/archive/11457
ttp://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.15
902デフォルトの名無しさん:2006/02/11(土) 23:13:45
>>901
ありがとうございます。
その二つは見つけてませんでした。すいません。

ただ、それほど面倒なことにはならないなぁってのが第一感想です
#もちろんきーつけて使えばの話ですが。
903デフォルトの名無しさん:2006/02/11(土) 23:13:51
delete this、の有用性は時と場合によるかと
すれどのラッパークラスとかの場合は便利

>>901
> CWnd::GetSafeHwnd()
目から鱗が2枚落ちました
904デフォルトの名無しさん:2006/02/12(日) 00:11:30
>>903
間違っても仮想関数で真似するなよ。
905デフォルトの名無しさん:2006/02/12(日) 00:52:09
>>903-904
ヌルポインタに対するメンバ関数呼び出しの時点で未定義動作だ。
仮想関数関係無しに真似しちゃイカン。
906デフォルトの名無しさん:2006/02/12(日) 00:55:24
>>905
やべ、そうだったのか。
ってことは

struct tree{
    int value;
    tree*left,*right;
    int size(){
        return this?left->size()+right->size()+1:0;
    }
};

こういうソースは駄目なのか......
んー面倒だなー
907デフォルトの名無しさん:2006/02/12(日) 01:37:01
>>906

そんなソース、貧乏人しか書かない時代なんだが。
908906:2006/02/12(日) 01:44:25
いや、まぁこれ位ならsetなりmultisetなりを使うけどさ、
これ以外にも自己再帰的なデータ構造を扱うときに
this==NULLを終端条件とした再帰を書きたくならない?

俺は結構なるけどなー。まぁ未定義らしいしやめとくか
909デフォルトの名無しさん:2006/02/12(日) 02:25:34
910デフォルトの名無しさん:2006/02/12(日) 11:37:35
>>905
あらま・・ヌルオブジェクトパターンを簡易に書けるかと思ったら
VC限定仕様だったみたいですね

>>906もそれは同じ・・かな
911デフォルトの名無しさん:2006/02/13(月) 01:39:14
限定とは言わんが、鼻から悪魔だな。
912デフォルトの名無しさん:2006/02/14(火) 04:42:44
operator<<と>>を間違えていたのに気づかず、こんな時間だ。
なぜこんなにもSTLのエラーメッセージはわかりづらいのだろう?
913デフォルトの名無しさん:2006/02/14(火) 05:14:32
>>912
それはあなたが馬鹿だからです。
914デフォルトの名無しさん:2006/02/14(火) 08:06:20
馬鹿を切り捨てるわかりづらさは問題だよなやっぱ。
915デフォルトの名無しさん:2006/02/14(火) 08:40:35
そういうひとはVBを使ってください
916デフォルトの名無しさん:2006/02/14(火) 09:43:15
いやー、ロジックの方にばかり目がいってしまった。
std::istream& operator<<(std::istream& is, myclass& o);
('A`)…
917デフォルトの名無しさん:2006/02/14(火) 09:49:52
ところで、引数付きコンストラクタで
配列を初期化しながら確保できるようにはならんかね?
デフォルトコンストラクタ無いとだめか。

しかし、初期化漏れを防ぐために敢えて
デフォルトコンストラクタを作ってなかったのだが・・・
918デフォルトの名無しさん:2006/02/14(火) 09:51:17
>>912
g++ だろ?
エラーメッセージ翻訳フィルタでも作ればウケるかも
919デフォルトの名無しさん:2006/02/14(火) 09:59:17
>>917
std::vector じゃダメか?コピーコンストラクタ要るけど。
920デフォルトの名無しさん:2006/02/14(火) 10:34:45
>>917
struct Point
{
  int x, y;
  Point( int a, int b ) : x(a), y(b){}
};

Point points[] ={
  Point( 0, 0 ), Point( 0, 1 ), Point( 1, 0 ), Point( 1, 1 )
};

普通にできるが…
921デフォルトの名無しさん:2006/02/14(火) 10:46:16
>>919 なるほど、そういや何も考えずに std::vector<OreClass> してたな。
あれが通ってたのはコピーコンストラクタがあったからか。
しかし内部の実装みてないけどコピーコンストラクタがあったとしても
なんでそれで通るんだろう。ていうか、初期化されてるんだろうか。

>>920 そういう形式の初期化はできますね。
配列の要素一つごとにざくっとコンストラクタ
呼んでくれればべんりだなぁ、と。
922デフォルトの名無しさん:2006/02/14(火) 10:51:07
>>918 g++だ。他のコンパイラはもっと明確なエラーが出るのかな。

>>917
配列の要素一つごとに、異なる初期値を与えたいの?
923デフォルトの名無しさん:2006/02/14(火) 10:56:22
>>922 いや、たとえば

class ValuePair {
double v1;
double v2;
public:
ValuePair(double initial_v1, double initial_v2)
: v1(initial_v1), v2(initial_v2){}
};

というクラスを作っておいて、

ValuePair value_pairs[100](0.5, 0.6);

のようにして全部同じコンストラクタ連続的に呼んでくれたらな、って。
924デフォルトの名無しさん:2006/02/14(火) 11:02:29
struct OreGenerator
{
  OreClass value;
  OreGenerator() : value( 10, 0 ){} // 適当な初期値
  operator OreClass() const{ return value; }
};

std::vector<OreGenerator> v( 100 );
OreClass ore = v[0];
925デフォルトの名無しさん:2006/02/14(火) 11:09:35
>>923
テンプレート関数の実装は、必要になるまでコンパイルされない。
よって、std::vectorも、要素のデフォルトコンストラクタは
実際に必要になるまで呼ばれない。

その用途なら、以下のコードで十分。

ValuePair value( 0.5, 0.6 );
std::vector<ValuePair> value_pairs( 100, value );
926デフォルトの名無しさん:2006/02/14(火) 11:09:58
うむぅ、ファクトリか。
927デフォルトの名無しさん:2006/02/14(火) 11:12:43
>>925 ども。
それが一番すっきりしそうですね。
幸い operator= は定義済みですし。

コンテナクラスライブラリってオーバーヘッドやだな、
なんて思ってたんですが、std::vector<T> って中身は
まんま配列っぽい。
928デフォルトの名無しさん:2006/02/14(火) 11:20:26
OreはねーよOreは
929デフォルトの名無しさん:2006/02/14(火) 11:35:00
それにしてもテンプレート使うと、エラーが出たときに
テンプレートクラスを定義しているヘッダファイルの
行番号が表示されるから、いったいどこの実体化で
エラーになったのか分かりづらいっすね。
930デフォルトの名無しさん:2006/02/14(火) 12:13:57
struct X {
template <class T> f(int i, int j) {}
template <class T> operator()(int i, int j) {}
};

X x;

関数テンプレートで、引数からテンプレートパラメータが決まらない場合は
x.f<double>(1, 2);
のように明示することができます。
operator()の場合にはどのように呼び出せばよいですか。
x<double>(1, 2); // NG, undefined operator()
x.operator()<double>(1, 2); // OK, でもなんか見た目が変
931デフォルトの名無しさん:2006/02/14(火) 12:17:58
>>922
Borland なんかもうちっとマシなメッセージ吐くぞ
ときどき日本語おかしかったりするけど
932デフォルトの名無しさん:2006/02/14(火) 12:22:38
>>930
見た目変ですけれど,それが正しい構文ですしそれ以外にないと思います.
呼び出し側でキャストをかけるとか,
type2type な形で型の情報を引数として引き渡せるようにするとか,
いくつか改善策はあるとは思いますけれど,決定的なものはないかと.
933デフォルトの名無しさん:2006/02/14(火) 14:02:46
>>930
templateメソッドは引数の型で
一意に定まった方が使いやすい
934デフォルトの名無しさん:2006/02/14(火) 14:27:09
int *ip;
void *vp;
〜略〜
*ip++ = 10;
*(int*)vp++ = 10;
とすると、「error C2036: 'void *' : サイズが不明です。」というエラーがでます

結局のところ、
*(int*)vp = 10; vp = (int*)vp + 1;
をやりたい訳なんですが、

*ip++ = 10;
みたいな書き方、voidポインタでは出来ませんか?
935デフォルトの名無しさん:2006/02/14(火) 14:31:58
演算子の優先順位:
* より 前置++/後置++ の方が後回し
936デフォルトの名無しさん:2006/02/14(火) 14:34:55
>>935
と思ったけど何か違うみたい
スルー推奨
937デフォルトの名無しさん:2006/02/14(火) 14:49:17
>>934
*((int*)vp)++
だとうまくいくみたい。
キャストと++は同順位で右左だから、という説明でいいのかな。
938デフォルトの名無しさん:2006/02/14(火) 14:52:58
>>934
無名の共用体を使っては?
939デフォルトの名無しさん:2006/02/14(火) 14:53:51
>>937
非標準
940デフォルトの名無しさん:2006/02/14(火) 15:36:40
>>937
それVC++2003toolkitだとC2105だった。
941937:2006/02/14(火) 16:41:41
ほんとだ。g++でも怒られた。bccと俺が甘いってことか。
すまんかった>934
942デフォルトの名無しさん:2006/02/14(火) 17:27:47
>キャストと++は同順位で右左だから、という説明でいいのかな。

よくない

規格票でも K&R でもいいが、
単項と後置の優先順位を確認してみては?
943934:2006/02/14(火) 17:36:22
いろいろありがとうございました。
そういう事は出来ない感じと、受け止めましたので

*(int*)vp = 10; vp = (int*)vp + 1;
で行きますです。m(_ _)m
944デフォルトの名無しさん:2006/02/14(火) 17:42:02
>>943
union {
int* ip;
void* vp;
};
cout << vp;
ip++;
cout << vp;
は試したか?
945デフォルトの名無しさん:2006/02/14(火) 18:06:11
>>934
組み込み型のインクリメント演算子などのオペランドには左辺値が必要。
だからこうして参照を使えばとりあえずできる。
typedef int* pint;
*reinterpret_cast<pint&>(vp)++ = 10;

ちなみにtypedefを使わないでやるとするとreinterpret_cast<int&*>(vp)になる。
946934:2006/02/14(火) 18:10:29
>>944
無名共用体を使う場合、どうやるのかイメージが湧きませんでした。
なるほど、そういう意味だったのですね!
vpが引数で与えられてるので、共用体でやるとしたら、無名じゃない共用体で、という事でしょうか。
それでも、共用体の方が可読性いいかもしれませんね。
ありがとうございました。
947934:2006/02/14(火) 18:13:34
>>945
reinterpret_cast<int&*>(vp)
すみません・・・これ、なんという手法ですか?
勉強不足でお恥ずかしいのですが、よく知らないのです。
ググってきますので、ヒント下さいますでしょうか?
948デフォルトの名無しさん:2006/02/14(火) 18:15:32
C++さんです
949デフォルトの名無しさん:2006/02/14(火) 18:18:28
>>948
ワラタ
950デフォルトの名無しさん:2006/02/14(火) 18:28:27
>>945
int&* って何だ? ( int*& なら知ってるが)
951945:2006/02/14(火) 19:03:00
>>950
しまった_| ̄|○
952デフォルトの名無しさん:2006/02/14(火) 22:39:54
>>944,945
実装依存なのはわかって言ってるんだろうな?
953デフォルトの名無しさん:2006/02/14(火) 23:10:53
>>952
void* が必要な場面で実装非依存とは、例えば?
954デフォルトの名無しさん:2006/02/14(火) 23:15:34
>>953
>>952じゃないけど、たとえば

void somefunc(void (*fp)(void *, int), void *dat)
{
  fp(dat, 4);
}

void f(void *pi, int n)
{
  std::cout << n + static_cast<int *>(pi)[3];
}

void g()
{
  int a[10];
  somefunc(f, a);
}
955デフォルトの名無しさん:2006/02/14(火) 23:26:15
>>953 pthread_create() とか。
956デフォルトの名無しさん:2006/02/14(火) 23:26:45
>>954
意図が見えない
もともと int* だったのが明らかでキャストし直していると言うならそもそも void* にする必要性はないし
例えばと言ったのはコード片じゃなく応用分野だ

int* pi = 0;
void* pv = pi;

こんなのをわざわざ尋ねたりはしない
957デフォルトの名無しさん:2006/02/14(火) 23:35:55
バイトストリームを生成する関数とか
958デフォルトの名無しさん:2006/02/14(火) 23:40:02
>>956
somefuncはライブラリ関数で、コールバックと、それに渡す補助データとしてvoid *の値を取る、と考えてくれ。
somefuncのユーザは、コールバックにint *を渡したいが、型を合わせるためにいったんvoid *にキャストして渡し、
それをコールバックで受けてint *に戻して使う。
959958:2006/02/14(火) 23:40:54
こんな例出さなくてもqsortで十分だった…
960デフォルトの名無しさん:2006/02/14(火) 23:41:04
>>957
エンディアンはどーすんべ?
961デフォルトの名無しさん:2006/02/14(火) 23:42:01
次スレはどーすんべ?
962デフォルトの名無しさん:2006/02/14(火) 23:43:22
>>959
qsort がしていることと >>944-945 は何が違う?
963デフォルトの名無しさん:2006/02/14(火) 23:43:43
>>960
関係無い話を持ち出すな。
964デフォルトの名無しさん:2006/02/14(火) 23:45:00
>>959
<algorithm> ではなく extern "C" 関数を使う場面とその理由は?
965デフォルトの名無しさん:2006/02/14(火) 23:45:08
ほんとに初歩的な質問。
初歩的過ぎてなんて調べたら良いのか分からないのでここで。

a[1][1],a1][2],a[2][1]a[2][2] = 1;
ってやるとエラー吐くんですけど、括弧とかどこに付けたら良いですかね(´・ω・`)
966958:2006/02/14(火) 23:45:11
>>962
何を言ってるのかよく分からん。
俺は>>953にレスしただけで、直接>>944-945にコメントしたわけじゃない。
967デフォルトの名無しさん:2006/02/14(火) 23:45:18
>>963
実装依存かどうかが論点のはず
968デフォルトの名無しさん:2006/02/14(火) 23:46:07
>>962
944,945 は void* と int* の表現形式に互換性があることに依存している。
例えば void* が 64bit で int* が 32bit だったら不味いことになる。
969958:2006/02/14(火) 23:46:45
>>964
説明のためだから。

>>965
何がしたい?四箇所に一を代入したいなら、
a[1][1] = a[1][2] = a[2][1] = a[2][2] = 1;
970965:2006/02/14(火) 23:47:56
>>969
どうもです。今までわざわざ四回書いてたので同時に代入する方法知りたいと思ったわけです
ありがとうございました
971デフォルトの名無しさん:2006/02/14(火) 23:56:24
>>967 「何が」実装依存であるのか考えろ。
972デフォルトの名無しさん:2006/02/14(火) 23:57:15
>>968
そんなら qsort も実装依存ですな

>>969
じゃ、>>956 へのレスとして何の説明がしたかったんだ??
973デフォルトの名無しさん:2006/02/15(水) 00:00:40
>>971
「何が」の違いは今あなたが持ち出したことだ
974958:2006/02/15(水) 00:03:31
>>972
>そんなら qsort も実装依存ですな
int *とvoid *の表現形式が違ったとしても、
int *からvoid *に変換し、それをさらにint *に戻したとき、
これが最初の値と変わらないことは規格で保障されている。
だから、qsortは実装依存ではない。

>じゃ、>>956 へのレスとして何の説明がしたかったんだ??
実装に依存せずにvoid *を使うことができる、ということ。
975デフォルトの名無しさん:2006/02/15(水) 00:07:25
int compare(int* a, int* b) { ... }

を渡すして動作するかどうかは処理系依存。


int compare(void* va, void* vb) {
 int* a = (int*)va;
 int* b = (int*)vb;
 ...
}

なら良い!
976デフォルトの名無しさん:2006/02/15(水) 00:07:45
お前らの話はよーーーく分かった

だから、次スレよろ
977デフォルトの名無しさん:2006/02/15(水) 00:10:12
自分が間違ってるかもしれないという可能性を認められないガキが紛れ込んだな。
さっさと次スレに移るか。
978デフォルトの名無しさん:2006/02/15(水) 00:16:31
>>968
任意のデータ型のポインタをvoid*に代入し
再度元のデータ型に戻すと、元のポインタが確実に復元できることは規格で保証されている。
・・・Cでは。

C++でも、Cスタイル/static/reinterpretなキャストなら
(つーか、void*にdynamic_castとか出来ないし)
保証されていそうな気がするが。
979v(^・^)v:2006/02/15(水) 00:17:12
今テンプレ整理してるからもうちょっと待ってて。
980デフォルトの名無しさん:2006/02/15(水) 00:17:34
981デフォルトの名無しさん:2006/02/15(水) 00:18:35
正直正規表現わかりにクス
while($s =~ /^(.).*/g)
とか

$a =~ s/^(.)//;
とか
意味わからなす・・
perl
これをC++でよろしく。
982デフォルトの名無しさん:2006/02/15(水) 00:20:31
983デフォルトの名無しさん:2006/02/15(水) 00:22:14
>>981
状態遷移表くらい書けるようになっとけよ
984デフォルトの名無しさん:2006/02/15(水) 00:22:20
985デフォルトの名無しさん:2006/02/15(水) 00:23:19
>>978
>>968はそんなこと分かってると思うんだが。
>>968が問題にしてるのは、正規の変換を経ずに
unionや参照のキャストを使ってvoid *をint *として扱った場合の話だろ。
986デフォルトの名無しさん:2006/02/15(水) 00:23:54
>>981
上は$sという変数に、^(.).*でパターンマッチした結果を条件式にしてる
このパターンマッチだと、行がある限りだな

2個目は行先頭の1文字を消してる

多分これであってると思うが、違ってたらシラネ
987デフォルトの名無しさん:2006/02/15(水) 00:24:27
>>983
特に
$s =~ /^(.).*/g
とか

$a =~ s/^(.)//;
とか

いったい~から始まる奴が何して代入してるんだって感じだどもさ
ってか相談してもいいだろさー
988デフォルトの名無しさん:2006/02/15(水) 00:24:48
>>985
reinterpret_cast を何だと思っているわけ?
989デフォルトの名無しさん:2006/02/15(水) 00:25:29
>>986
そのちょっと最初は興味あったけど
やっぱ興味ないわーーー
ってところに女はほれたんだな・・そうなんだろ?
990デフォルトの名無しさん:2006/02/15(水) 00:27:01
988の続き

>>985
あなたが何を主張しているのかはわかった
991デフォルトの名無しさん:2006/02/15(水) 00:27:09
>>988
わけわからん。もうちょっとくわしく。
992デフォルトの名無しさん:2006/02/15(水) 00:29:06
reinterpret_castって一番好き勝手出来る奴だろ?
あれってC形式のキャストと変わらなくね
993デフォルトの名無しさん:2006/02/15(水) 00:29:28
>>991
static_cast ではなく reinterpret_cast を使う場合の理由と
無名の共用体を使う場合の理由はどう違うんだ?
994デフォルトの名無しさん:2006/02/15(水) 00:32:02
もうねstl作れ
さもなきゃdefineしろ
それもだめなら考えうる全ての型を実装しろ

ってこと?
次スレまだー?
995デフォルトの名無しさん:2006/02/15(水) 00:33:27
>>986
参考のサイトを参照しながら
$a =~ s/^(.)//;
はわかった。
Cでの書き方もおそらくわかると思うけど
$s =~ /^(.).*/g
もっと詳しく教えてくれ。
~ /^(.).これで一文字目と二文字目なのかな??

よくわからんからこれをCでどう書くのか

暇だったら世路。
996デフォルトの名無しさん:2006/02/15(水) 00:34:09
>>993
union {int *upi; void *upv} u;

int *pi;
void *pv;

pi = static_cast<int *>(pv); /* ok */
pi = reinterpret_cast<int *>(pv); /* ok; 上と同じ */
pi = reinterpret_cast<int *&>(pv); /* ng */
u.upv = pv;
pi = u.upi /* ng; 上と同じ */
997996:2006/02/15(水) 00:35:38
ごめん。
>pi = reinterpret_cast<int *>(pv); /* ok; 上と同じ */
これは無しで。
998デフォルトの名無しさん:2006/02/15(水) 00:37:04
>>995
解釈は間違ってはないけど微妙に違う
^(.)これが1文字目なのはいいけど、次のは
.じゃなく.*で二文字目以降(無くても可能)って意味

それと正規表現Cで書くってどういうことだ?
まさか自動羊肉実装するのか?
面倒だから鬼車使っとけ
999デフォルトの名無しさん:2006/02/15(水) 00:39:34
>>998
ふむなるほど。
いやなんかperlの奴を移植しようかと考えてるんだが
あわよくば
書いてくれるかなって思ったわけ。そこだけ





次スレナインか?
1000デフォルトの名無しさん:2006/02/15(水) 00:40:45
ここでVIPPERが華麗に1000げと
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。