STLつかうと一気に実行ファイルサイズが10倍に?! 環境によるだろ。 俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力 ランタイムを使用するようにして使っているが、例えばstd::vectorを 使っても使わない時と比べ10Kほどしか増えない。 すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。 C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。 とかいうエラーが出るんだけどこれってどうすればいいの? #include <stdafx.h> 後氏ね。 言葉が悪いな。それで教えているつもりか。 まぁヒントぐらいにはなったな。 うむごくろう。 テンプレは以上です。足りない所、間違っている所がありましたら、追加訂正よろ。
>>10 1レスで一気にやったら面白みがないだろ。
テンプレに面白みなんて求めるなよ
>>11 スマソ(´・ω・`)
レスを節約しようとしたんだけど。次回から別レスにするね。
何はともあれ乙。 ところでBoostの日本語文書といえばcppllの翻訳を抜かしていいのか?
メンバ関数ポインタの代入がコメント化した部分でコンパイルエラーがでてしまいます。 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のメンバ関数ポインタの代入はできないのでしょうか
p = &B::func;
>>17 それ、Borlandのコンパイラだろ。多分バグだよ。
gccだとちゃんとエラーが出るぞ。
そうです、BCCです 関数ポインタへの代入を全部p = &B::func;にしたらコンパイル通りました。 ありがとうございます。この書き方が正しいのですね。 …ではロベールさんとこの関数ポインタの書き方は、一体???
わかりました・・・
23 :
デフォルトの名無しさん :2006/01/09(月) 17:08:34
そのサイト、「メンバ関数ポインタ」でググると一番上に出てくるな
悪いsage忘れた
間違った知識を流布している時点で、害悪だな。
26 :
デフォルトの名無しさん :2006/01/10(火) 11:09:16
std::cerr の rdbuf をプログラム開始時に ファイルストリームに変更して、 出力をファイルに落としています。 ofstream ofs("out.txt"); std::cerr.rdbuf(ofs.rdbuf()); 場合によってはエラー出力を抑制したいことがあるのですが、 Windows なので /dev/null に出力するということもできません。 ヌルデバイスを表現するストリームというモノは 標準で用意されてるモノなのでしょうか?
>>26 /dev/nullがあるから、標準では用意されなかったんだろ。
WindowsはNULにでも出すしかないな。
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 ....以下続く
スレ違い。sageろ。死ねばいいのに
>>30 なんですれ違いなのか理解不能だが
切々と語ってくれ
sageについては正直すまんかった
言語と環境の区別くらい付けてくれ。
なんか2chは無条件にsageなきゃいけないと思ってる奴が時々いるな。 技術系の板で質問でageるのは普通だろ。
ぶっちゃけPC初心者板でもなきゃageる意味無い。 VBスレが上がっててもVB知らなきゃ答えられんし
知ってる奴に見てもらえりゃいいんだから別にいいだろ。
36 :
デフォルトの名無しさん :2006/01/10(火) 20:11:36
iostream の std::endl は、改行文字を出力した後に バッファをフラッシュしてくれるマニピュレータですが、 この改行文字は固定なのでしょうか? CR/LF/CR+LF を何らかのフラグで切り替える ということは出来ないでしょうか?
>>33 もうsage強迫観念だよな、精神病の一種だw
なんでそんなになっちゃったんだろう
すみません。
坊主憎けりゃ袈裟まで憎い。
スレ違いに腹をたてたばかりに、ageまで憎く思えてしまいました。
ちなみに、
>>31 の
「言語と環境の区別くらい付けてくれ」は、いまいちでした。
「もっと適したスレがある」というべきでした。
反省しています。
40 :
36 :2006/01/10(火) 20:51:34
やはり ios::binary でオープンして、 '\x0a' を出力するしかないのかなぁ。
41 :
36 :2006/01/10(火) 20:59:25
Visual C++ 2005 でしか確認していないのですが、 std::endl は結局のところ "\n" を出力している だけで、それを受けたストリームが 通常の '\n' の解釈にしたがって改行コードを 出力しているだけですね。
WinとかMacって\rだと何が出力されるの? UNIXだと普通に \r CR \n LF だが
43 :
デフォルトの名無しさん :2006/01/10(火) 21:29:20
自分でマニピュレータ定義した方が早いのでは?
昔調べた結果 出力文字 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
>>44 おおそうなっているのか
Winはdosと変わってないんだよね?
MacもOSXと昔のMacOSで変わってないのかな?
>>45 UnixもDOSもMacもASCIIを使っているのでそのとおり。
ついでに言えばストリームをバイナリモードにすればどれもUnixと同じくそのままの文字が出力されるはず。
何かのポインタ型をtemplateの型として受け取ったとき、 なんとかtemplate内部で、そのポインタ型の、ポインタじゃないインスタンスを生成する方法ないすかねぇ。 int main(){ Hoge<int*> hoge; hoge.create(); } と、した時 template <class TPTR> class Hoge{ TPTR p; void create(){ //ここで p = new int; としたいのですが……無理っすかねぇ。 } } 最初からHoge<int>を前提としてtemplate書けって感じですが、そこをなんとか
あ、mainが返値なくてすいません
>>48 Hogeのテンプレート引数は必ずポインタ型であることが必要なら、
初めから元の型をテンプレート引数に取るようにするのが一番楽。
template <class T> class Hoge{
T *p;
void create(){
p = new T;
}
};
それが駄目ならboost::remove_pointer<T>
>>49 mainだけはintを返すように宣言してあり、なおかつreturnがなければ
return 0;が行われるという扱いがなされるから問題ない。
>>50 レスありがとうございますx2
remove_pointerのソース観てみましたが、いやはやさっぱり分かりません。
もとからない自信が、すっかり無くなってしまいました。
やはりそうですよね…おとなしく書き直すことにします。変更個所オオス!!
>>51 boost::remove_pointer<int *>::typeはintになっているという具合。
char* func() { char *str = new char[100]; char* retstr = str; delete str; return retstr; }; こういう書きかたってマズイんでしょうか。
>>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;
     }
};
テンプレートに慣れていないせいなのかなんかキモイ。
やはり普通に元の型でやるべきだと思った。
56 :
53 :2006/01/11(水) 02:46:41
よくよく考えてみればマズイですね。 コードに意味はなくなんとなく考えてみただけです。 有難うございました。
>>53 そこの delete は delete [] な。
>>44 実際にはコンパイラ(のランタイムライブラリ)によって変わるみたいだよ。
だから例えば同じ dos 環境下でも Microsoft のコンパイラで作成したプログラムと
Borland のコンパイラで作成したプログラムでは結果が違う。
>>4 の表のdosの欄は恐らく
Microsoft のコンパイラで作成したプログラムでの結果だろうけど、Borland のコンパイラで
作成したプログラムの場合、"\r\n" の出力結果は "\r\n" のままになる。
cf.
http://www.trickpalace.net/cppll/reference/printf.htm ( このページの一番最後 )
まあそんなものに依存するプログラムは書くなってことだな
>55 typename 付けないといけないです template<typename TPTR> struct Hoge { TPTR p; void create() { p = new typename remove_pointer<TPTR>::type; } };
61 :
55 :2006/01/11(水) 12:57:20
>>60 おっと、ごめん。
忘れてた。
VCで通ったのでそのまま書いてしまった。
前すれにストリームの解説を求めてた人がいたけど、 標準ライブラリの解説は、ここが参考になる。 //www.cc.nao.ac.jp/fsunman/japanese/C++/index.html
>>55 さん他
うーん、凄い…ありがとうございます。
ここまで簡単に書いて頂いたのに、理解できない自分に絶望ですが。
何故こうなるんだろ…。奥が深いですねぇ(俺には)。
こういう怪しげなテンプレートの使い方はModern C++ Designで勉強するしかないな。 テンプレートがもう少し使いやすい概念になってくれるとありがたいんだけどな。
Modern C++ Design は序盤のタイプリストまわりが超難解、 template<template<template<hoge>,hoge>,hoge> とかの 多段テンプレートってのはLispの書式に近いんだそうだが、 そのLispの書式がこれまたわけわからんかったりする。
要はcarとcdrをtemplateを駆使して実装してる感じか
最近はそういう再帰的なテンプレートと並行して, テンプレートクラスを1つの関数とみなして使う使い方も重要かと. boost::mpl, boost::type_traits あたりは後者の見方がないと なかなか使いこなせないように思うのですが.
実験データが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が出ないと駄目。
>>68 実験データひとつを、ひとつの文字列として読み出し、
文字列の後ろから小数点を検索して距離を調べ、
見つかれば距離に応じた値が答え。見つからなければ1。
C++関係無いな。
Cなら scanf("%s.%[^ ]", null, po) みたいな感じで読めそうだけどC++核のは面倒くさそうだな
- C++核 + C++っぽく書く
72 :
68 :2006/01/14(土) 02:57:44
10底のlog取るだけジャン
それよりは文字列として'.'を探してやるほうが早そうな気がする。
ごめん嘘 速度以前に題意に即さなかった
>>73 ただし、1.20とかって数字のときにも、
0.1ではなく0.01が出ないと駄目。
よく嫁
77 :
68 :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.; }
ちょっと気になるのが、 dotPosがsigned型であることと、return 1だな。
80 :
デフォルトの名無しさん :2006/01/14(土) 16:26:06
jya, return 2 ni suruyo
俺ならintじゃなくて必ずstring::size_typeにするけど、神経質かなぁ?
>>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;
}
83 :
82 :2006/01/14(土) 16:39:17
うは。 pow の引数 signed にキャストしないとえらいことになるな。
符号なしは怖いです for(;i>=0; i--)
85 :
82 :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; }
>>82 stringのメンバlengthとsizeは全く同じだよ。好きなほうを選べばいい。
>>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()を使う方法ないんでしょうか?
>>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) } とかと同時に使いたい
>>90 それは Base を使ってる限り無理だな。
ローカルな配列に一旦コピーして、後で戻すことができれば
同じ結果にできるだろうけど。
>>90 > func(int *p_xy){ return *p_xy + *(++p_xy) }
これは未定義動作だな。メモリー上の連続性とか関係無しに。
Derivedでint &x_を宣言したってBaseのメンバ関数からは Base::x_しかみえんだろうが。 doSomeをオーバーライドしない限りどうしようもなかろうに。
>>92 直前の副作用完了点から次の副作用完了点までの間で
同一オブジェクトに対して読み取りや変更が行われる回数は
高々1度でなければならないってのだっけ?よく覚えてないが。
>>95 具体的に言ってしまえば*p_xyと*(++p_xy)のどちらが
先に評価されるか未定義になってる。
97 :
デフォルトの名無しさん :2006/01/14(土) 23:41:16
Derived を Baseにcastとか・・・
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 に格納したいのですが、 可能でしょうか?
可能です
103 :
デフォルトの名無しさん :2006/01/15(日) 11:44:32
>>102 ありがとうございました。
いままで scanf を使っていたのですが、
C++ のストリームを使う方が安全だし便利ですね。
その代わりコストは付くがな。 最近じゃCRTの可変長引数関数にタイプチェックあるんだっけ? VC8.0限定だった気もするけど。
あんなもんサイズ間違えたら終いだ その前にまず標準に準拠しろと
106 :
デフォルトの名無しさん :2006/01/15(日) 13:30:32
>>104 scanf の方がむしろ書式文字列をパースする
必要があるので、コストつきそうな気もする。
>>100 オレも ICU で落ち着いてる。つか、 ICU で良いんじゃね?
他の国際化の機能まで視野に入れると iconv より俄然強力だし
少なくとも std::codecvt よりはマシと思うw
110 :
デフォルトの名無しさん :2006/01/15(日) 16:45:44
すみません、double以上の数字の計算ってどうやってするんですか?
112 :
100 :2006/01/15(日) 18:44:37
>>108 iconv は手軽だけど char のみの対応
std::codecvt は使い方がよく判らん + C/C++ 各環境の実装が胡散臭い(wchar_t が 2byteとか)
ICU は大がかりだけど独自UChar に安心感が・・・
その結果で ICU に落ち着きそうな俺ガイル
詳しそうな人の意見が聞けて嬉しいなり
>>109 入れるの忘れてた
それも気になる気になる
レスどーもでした
参考になります、ありがとうございました
ATLを使うへたれな俺。
115 :
100 :2006/01/16(月) 03:10:29
基底クラスから、 派生クラスのメンバ関数ポインタ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れていません、と怒られます
>>116 やりたいことはなんとなく想像尽くけど、別の方法を検討した方がいいと思う。
一番無難なのは、結局基底クラスにexecute関数をvirtualで持って、
派生クラスの内部で状態によって分岐だね。
派生した処理関数の呼び出し方にトリッキーな方法はいくらでもあるけど、
コンパイラの実装依存とかになりやすいし、変に複雑になるんなら
基本に立ち返るのが吉
わかりました。 基本に立ち返ります。
Boost.Regex が、ICU に対応したからこれから使うなら ICU じゃね? ただ、Boost や STL のコード中に紛れ込むと違和感は歩けど。
>>116 派生じゃなくてテンプレートを使うのはどうかな?
//base
template class Events<class HandlerT>
{
void event1()
{
Handler::event1();
}
...
};
//derived
class Handler
{
void event1()
{
printf("event1");
}
...
};
Event<Handler> EventHandler;
まちがえた
>>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 = ...} }; というスタイルで処理しています。 けれどやっぱりべた書きのほうがいいのかとも悩んでます。 どちらのほうがいいのでしょうか?
メンバ関数の中で delete this; と自分自身を削除するのはアリなんでしょうか?
合法ではある。
>>126 そのコードを活かして type2 の替わりに CDoSome1 を使うと、
何らかの結果が格納されていることが保証できる。
それが利点にならないのなら、ほとんど無駄な感じ。
CDoSome2 辺りは、たぶん間違い。
一般的に、クラスが存在する意味を他の人にも
説明できないようなら、クラスを作るべきじゃない。
>126 最近俺も、戻り値が複数ある関数をクラス化してみたりしてる。 が、コンストラクタで処理を実行するのは如何なものか? 判りにくいから継承もするべきではないと思う。
戻り値が複数あるような関数は、 いつもクラス・構造体を返す関数にしている。
二つくらいならポインタ渡して代入させてる。
135 :
デフォルトの名無しさん :2006/01/18(水) 03:46:38
関数の後にはすべて throw() などとして どんな例外を投げるかとかを指定するべきでしょうか?
>>135 例外仕様はむしろ避けるべき。
詳しくはC++ Coding Standardsの第75項あたりを参照のこと。
137 :
デフォルトの名無しさん :2006/01/18(水) 04:20:37
ふむ、やっぱ買わなきゃならんか。 32ドルくらいだし買うか、生協で。 その本の内容を読まずにレスするけど、 例外つかわないってのがトレンドなのか? コンストラクタで例外投げるのは時々躊躇することがあるが。
例外を使わないんじゃなくて、例外仕様を使わないのがトレンドなんじゃない? 例外はむしろ使うべきだろ。 コンストラクタでは特に。 デストラクタで投げちゃいかんけど。
139 :
デフォルトの名無しさん :2006/01/18(水) 04:33:06
あ〜そういう意味での「例外仕様」か。納得。 C++ の規格に含まれる例外つー仕様は使うな、 ってことかと思た。 コンストラクタでの例外を投げるのを躊躇するってのは、 投げないって言う意味じゃなくてコンストラクタ内での 投げる場所について慎重になるって意味ね。 中途半端に初期化された状態ってのが怖くて。 ところで、いまさら何をですまんが、 例外でコンストラクタを抜けるときって そのオブジェクトの *this について デストラクタ呼ばれるんだっけ?
呼ばれないというのを前提で生きてきたんだけど。
呼ばれない
>>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 にしとくとか。
>>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] も解放されるね。
>>147 とくに効率が問題にならなければ std::vector を
使っておいたほうがいいんじゃないか?
class Hoge
{
std::vector<char> member1;
std::vector<char> member2;
public:
Hoge() : member1(100), member2(100)
{}
};
>>148 今はそういうことを問題にしてるんじゃないんだけど。
150 :
デフォルトの名無しさん :2006/01/18(水) 12:25:20
>>147-149 まぁ、仲良くしとけ。
効率重視なら std::auto_ptr でよくないか?
これでもちゃんと開放されるだろ?
>>150 >>147-149 のように配列を構築したいときには駄目
auto_ptrが呼び出すのはdeleteだから。
配列の場合delete[]を呼ばないといけないですからね。
# 標準ライブラリにauto_ptrに対応するauto_arrayがないのが惜しまれる
auto_ptrを使ってしまうとコピーコンストラクタを書くのが面倒になるんだよな。
153 :
デフォルトの名無しさん :2006/01/18(水) 12:36:31
んじゃ、boost::shared_array だったらおk?
おkじゃない? 遅いからって嫌がる人もいるけど。
155 :
デフォルトの名無しさん :2006/01/18(水) 12:39:26
>>147 俺、いままで boost::coped_array でいいところを
boost::shared_array 使って書いていたみたいだ。
例外仕様がガラクタ認定なのは面白いよな Javaかわいそう
VC++じゃthrow()しか対応してないしなぁ
158 :
自分用メモ :2006/01/18(水) 12:47:25
つまり例外仕様は使うな、でFAってことだな
お願いします。 int x; xに値を代入(0から99)のときに、xが0から9までのときは、 00、01、、、09みたいに頭に0が付くように出力する簡単な方法はないでしょうか。 setwを使うと0が出ません。はじめにケタを調べればできますが、もっといい 方法はないでしょうか。
cout << setw(2) << setfill('0') << x << endl;
例外仕様は絶対に使わないってルール決めがあれば throw をマクロで弄って __FILE__ と __LINE__ を例外オブジェクトに付加したり catch されなくても自分で出した例外を throw の時点で全部ログに吐くなんて使い方もできるしなぁ。 まぁ、C++の規格的には予約語である throw をマクロで弄る時点で違法だけどw
>>160 素直に printf 使おうぜ!
printf("%02.2d\n", x);
>>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); と等価なようなことをやろうと思っているんですが、型が違う場合はポインタをバラバラに保持するしかないでしょうか?
>>166 仮に型が違う関数ポインタをまとめてコンテナに入れられたとしても、
関数を呼び出すときには、適切な型にキャストしてやらなきゃならないんだから
別々に保持しても変わらないと思うが
>>166 「型が違う」ってどの程度違う?
その例だと、(10, 10)で呼び出しているから、
・型はT (T1, T2)という形であり、
・int -> T1, int -> T2の暗黙の変換がある。
という条件を仮定している。
こういう条件があるなら、細かい型の違いを無視して
boost::function<void (int, int)>に入れられたと思う。
169 :
166 :2006/01/18(水) 16:02:44
>>167 やっぱり呼び出すときに型情報が要りますよね・・
intにマップしたEVENTXから関数ポインタの型を取得するようなtemplate書こうと思ったけど
結局そのテンプレートにアクセスするときに型が必要で意味なかった orz
>>168 ありがとう。でも引数の数と型から返り値の型まで違うんでboost::functionは無理そうです。
170 :
162 :2006/01/18(水) 16:53:52
>>165 バグベアードを作る時に違法じゃないか一応調べてさぁ
>17.4.3.1.1 マクロ名
>1 ヘッダ中でマクロとして定義された名前は,翻訳単位がそのヘッダを取り込んだ場合,いか
>なる用途に対しても,処理系用に予約する。
>2 ヘッダを取り込んだ翻訳単位は,そのヘッダ中で宣言又は定義された名前を定義するマクロを
>含んでいてはならない。更に,そのような翻訳単位は,字句的にキーワードと一致する名前をマ
>クロとして定義してはならない。
てなモノを見つけて、「キーワード(予約語)はマクロで定義するのは違法」って解釈したんだけど、
俺の解釈がなんか間違ってる?
# で、まぁ、違法と認識しつつ結局そのままバグベアードを作ったんだけどw
違法て・・・
違法等等以前に大混乱の危険
174 :
デフォルトの名無しさん :2006/01/18(水) 19:14:31
自作のデータベースから任意の検索条件で検索を行い、 検索結果を一覧で表示するプログラム をc++builder6で作成するプログラムがわかりません。 どなたか教えてください。
そんなものありません
宿題だろこれ、たぶん。
>>174 「自作のデータベース」
これ大変な事だぞ。一から作れって言うのか。
BDE使ったらだめなのか。
そんな事より、 「プログラムをc++builder6で作成するプログラム」 これ大変な事だぞ。
うむ。完成したら俺にもくれ。
181 :
デフォルトの名無しさん :2006/01/18(水) 23:08:47
ちょっと質問 boost::tokenizer::iterator itで(特にコレに限らないけど) func( *it++, *it ); だと引数の評価順序は不定でしたっけ?
184 :
デフォルトの名無しさん :2006/01/18(水) 23:28:26
//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++の良さを失っていそうな気もします。
>>185 Efficient C++だったかに、そういう実装のやり方について書いてあった。
ビルドに要する時間をできるだけ短くするために、そうすることもあると。
>>186 良かった、オーソライズして頂き安心しました。
レスありがとうございました。
>>185 >hoge.cppでしか使わないhoge_compの宣言と実装
分量にもよるけどhoge_comp.hの内容をhoge.cppに書いて
hoge_comp.hを無しにしてもいいかもね
189 :
uroko :2006/01/19(木) 16:59:25
Modern C++ Design っていう本を読んでいるんですが難しくてよくわかりません。 本の内容に関する質問はこのスレでもよいですか?
いいんじゃない?
191 :
uroko :2006/01/19(木) 17:04:46
では、今は仕事中でもあるので後ほど質問を内容を整理して 質問します。よろしくです。
unkoかとオモタ
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; ...
195 :
194 :2006/01/19(木) 17:52:25
環境を書き忘れました。 VC.net 2003です。先日までVC6.0を使用していました。
>>194 たぶんコンパイラ・デバッガの仕業。
未初期化の変数の値を読み込もうとするとエラーにするコンパイラ・デバッガを俺は知っている。
197 :
194 :2006/01/19(木) 17:58:28
>>196 返答ありがとうございます。
一応ソースコードには間にZeroMemory関数を使用して初期化しているのですが
結局だめでした。
また関数にポインタも渡せなくて困っています・・・
198 :
196 :2006/01/19(木) 17:58:44
>>195 やっぱりそうだ。
VC++ .Net 2003では196のとおり。変数をきちんと初期化すれば良い。
ただの構造体をnewしただけでは初期化されない(0埋めなどされない)
199 :
196 :2006/01/19(木) 18:01:13
忘れていた。こうすれば0初期化される。 TEST * test = new TEST();
200 :
デフォルトの名無しさん :2006/01/19(木) 18:06:04
今日からようやくクラスのお勉強に入ります。
連絡不要
202 :
194 :2006/01/19(木) 18:12:06
>>198 >>199 ありがとうございました。
参考になります。
グローバル変数で
POINT * p_test;
を定義したら中身が見えるようになりました。
お騒がせしました。
あ、というか関数内で定義したポインタは中身見れないのは仕様なのですか?
>>202 あなたがやろうとしていることは、C++の流儀には従っていないと思われる。
「こう書けばコンパイルが通るから」という理由で、グローバル変数にするのはやめた方がいい。
void f() {
TEST* test = new TEST();
}
この場合、TEST型へのポインタtestのスコープは、関数f()内である。
(厳密には、testが宣言された次の文から、関数の最後の}まで)
従って、この関数f()の外からtestにアクセスすることはできない。
複数の関数からtestをアクセスしたければ、次のようなオプションが取れる:
1. アクセスしたいすべての関数にtestへのポインタを渡す
2. 関連のある関数をまとめ、testと共にクラス化する
蛇足だが、ZeroMemory()を使うより、_POINT, _TESTのコンストラクタで初期化した方がいいと思う。
204 :
uroko :2006/01/20(金) 01:03:04
>>189 質問1 (page x)
次のコードは、コンパイル時に評価を行うことができるassertマクロだそうです。
template<bool> struct CTAssert;
template<> struct CTAssert<true> {};
このCTAssertの使い方と、とういう状況のときに使うのかがわかりません。
(コンパイル時に評価をおこなう必要がある状況というのがわからない)
>>194 「未定義の値」とはどこに表示されるのか?
他の変数に代入すると発生するエラーの内容(エラーメッセージ)は?
ソース貼るなら実際に動かしてるソース貼れ。
それから、コンパイル通るのぐらい確認しろ。
typedef struct _POINT {...} POINT; は C++ では struct POINT {...}; でいい。
C で使うにしても struct _POINT は struct POINT にしとけ。
>>202 「中身が見える」というのがどういう状態のことを言ってるのかわからん。
>>203 エスパー乙。
test のスコープは厳密には次の文からではなく test の直後から。
207 :
uroko :2006/01/20(金) 08:23:47
>>206 ありがとうございます。よくわかりました。
208 :
デフォルトの名無しさん :2006/01/20(金) 15:22:15
プロセスが消費した時間を計測するために使える関数で、 getusage() というものは有るのでしょうか? 昔、どこかのスレッドで同様の質問をしたときに、 getusage() 使え、という回答を頂いたのですが、 getusage() なる関数の使い方を見つけることが できませんでした。 getusage() という関数は 実在するのでしょうか?
>>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( ) { ・・・ ・・・ }
>>210 > int a[ n ][ n ] ;
これが既にダメ。
>>210 いくつかの選択枝がある。
1. std::vector<std::vector<int> >
ただし、int[][]のようなメモリ上の連続性はないし、大きさの初期化が必要。
2. new
1.のデメリットに加えて、deleteが面倒くさい。
3. boost::multi_array
1.2.のデメリットはない。ただし、非標準。
4. その他
5.二次元以上の配列を使う奴は馬鹿
214 :
デフォルトの名無しさん :2006/01/20(金) 21:33:53
てんさぁ
オブジェクト指向で、グローバル変数なんて使いやがったらしたたかに殴る。
↓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の話になりそうだけど、こういうことって出来ないの?
>>217 それだと結局要素数は定数でなきゃいかんが。
(* (int (*) [10][10]) p)[1][2] = 3; 配列のポインタ使えばこんな多分こんな感じ。
int[][]が型じゃないから無理
なるほど、二次元配列へのポインタにいったんキャストしてから、 デリファレンスするのね。 #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 }
あ、でも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]); }
>>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でやった時には問題なかったんですが・・
void *から任意のポインタ型への変換は、明示的なキャストをする必要がある。 void **p=malloc( IndexSize+size*x*y ); ↓ void **p=(void **)malloc( IndexSize+size*x*y ) ;
>>224 void **p=(void**)malloc( IndexSize+size*x*y );
次からはどの行でエラーがでたのかちゃんと書こうな?
>>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
作ったプログラムが無事にコンパイルできました!
>>227 初期化がコンパイル通ってないのに挙動が確認できるのか?
ポインタを参照に reinterpret_cast して挙動がおかしいのは当たり前。
>>227 だからboost::multi_arrayを使えと。
とりあえず、ソース汚いですけど、これで比べてみてください。 #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;
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; }
>>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;
}
>>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); こんな書き方しかないのでしょうか?
>>235 処理系依存
確実に取得したいなら自前で仮想関数テーブルをエミュレートするしかない
>>235 諦めてメンバへのポインタを普通に使え。
>>227 要するに p は配列を指すポインタであるので、
配列を指す参照にキャストしてしまうと、間接参照のレベルが一段ずれてしまう。
配列を指す参照を用いるなら
((int (&) [10][10]) (*p)) [1][2] = 3; が正解
キャストを使おうとしている人がほとんどみたいだけど、それって 当然規格はその結果を保証してないよね?
えーと、ソースのみにローカルなclassを使うときに、 外部から見えないようにするために、namespace { } を使うのですが、 個人的に.cppにclassを書くので、class内部に実装もがんがん書くし さらに内部structなんかを持たせる時もある、 なーんて事をしていると、(エディタでソース全体を整形することも多いので) インデントが深くなってちょっと嫌な感じ。 で、 namespace { namespace local { class localclass; } } class local::localclass { ... }; using local::localclass; などという事を考えたのですが、 これ(無名のnamespaceのさらに内部のスコープだけを明示して使用)って合法ですか? vc,bcc,gcc等でのコンパイルは問題ないみたいですが。 (未定義のstatic変数のエラーメッセージで確認)
>240 (質問の意図を思いっきり無視して) namespaceでインデントしなければいい。
ほんとにそれで、大丈夫なんですか?
大丈夫だと思います
>>241 どもです。
>>242 xyzzyでソース全体を整形すると、勝手にインデントしてしまうのですよ・・・
#includeを使って
"namespace hogehoge {" だけのファイルと
"}" だけのファイルを
先頭と最後に入れてごまかそうとした事も。
>>245 > #includeを使って
インデントが深くなるよりもこっちの方が気持ち悪い。
狂おしいほどハゲドー
>>239 なぜそう思う?
malloc も operator new も 返す型は void* なんですが。
>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; }
(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;
a.cpp もしくは c.cpp の B b; をどっちか消せよw
>>250 Bのクラス宣言だけをB.hppに残して、定義をB.cppに移動する。
汎用的に使いたいってことなら、 a.cpp と c.cpp から B b; を消して b.cpp に書いて、 a.h と c.h から extern B b; を消して b.h に書いとけ。
何もかもが間違っている気がする。
256 :
250 :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;
}
これで使い方合ってるでしょうか?
257 :
250 :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 が検出されました。
コンパイルエラーになりました。
#include "stdafx.h" あと氏ね。
パブロフの犬を思い出した
>>258 言葉が悪いな。それで教えているつもりか。
まぁヒントにすらなっていないが、
うむごくろう。
短気は損気。 気長にマターリ…ねみぃ。。。
次期バージョンのC++では、 list<list<int>> l; と>>の間にスペース入れなくてよくなりそうな感じだね。
禿もそうしたいってD&Eに書いてたね
264 :
デフォルトの名無しさん :2006/01/22(日) 08:06:40
>>262 逆になんで今はスペース入れなきゃならないのか、理由がわからない。
構文解析上の都合
266 :
デフォルトの名無しさん :2006/01/22(日) 08:23:47
空白が入ってないと、パーサが混乱するんだろうか。
レキサは基本的に最長一致だから、構文解析の情報を持たせないと >>を1つのトークンと見なしちゃう
268 :
デフォルトの名無しさん :2006/01/22(日) 08:33:59
じゃ、古典的な lex & yacc なんかじゃ パースできないってことか。 現代のコンパイラはレキシカルアナライザが分離してないのが当たり前?
269 :
デフォルトの名無しさん :2006/01/22(日) 09:15:03
質問です 1万桁とかの計算はどうするんですか? 型宣言でlong doubleまでは掛け算割り算できるけどそれ以上の仕方が分かりません そこら辺も自作しないといけないんですk?
多倍長演算 自作するなりそこらに落ちてるライブラリを使うなりご自由に
271 :
デフォルトの名無しさん :2006/01/22(日) 09:21:42
>>270 有名どころっていえばなんでしょうか?
GNU多倍長整数ライブラリですか?
272 :
デフォルトの名無しさん :2006/01/22(日) 09:23:47
って、
>>269 は実数演算がしたいみたいだから、
GNU MP ライブラリでいいのか。
個人的にはboost::bigintに期待してたり
274 :
デフォルトの名無しさん :2006/01/22(日) 13:33:42
少なくとも g++ と cl.exe は予約語 export をさっさとサポートしる。 話はそれからだ。
>>274 exportはサポートしなくても標準に合致している事が保証されたから、
それはなかなか難しいだろう。
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); // ここでエラー }
>>277 メンバ関数のポインタから関数呼び出しをするには、演算子 ->* または .* を使う。
> typedef int (Func::*PFUNC)(std::string);
この typedef ができるのに呼び出し方がわからないってのは、不思議な感じだな。
>>279 ありがとうございます。277ですが、C言語は知っているので、
typedefはなんとなくわかっているつもりですが・・・。
>メンバ関数のポインタから関数呼び出しをするには、演算子 ->* または .* を使う。
すみません、具体的にどのように変更すればよいということですしょうか?
return (&pf)(str);を変更するということですよね?
>>281 すみません、君らと違って暇じゃないもので・・・
283 :
デフォルトの名無しさん :2006/01/22(日) 19:09:07
前方イテレータの方がランダムアクセスイテレータよりスピードやメモリ使用量が優れているとおっしゃるのですか?
>>281 コンパイルできますた。
return (this->*pf)(str);
でした。
>>283 誰もそんなこと言ってないんじゃないかな。
>>282 暇じゃないなら2chに書き込んで都合のいい回答を待つより
自分で調べた方がいいと思う。絶望的に調べ物が下手とかでないなら。
287 :
デフォルトの名無しさん :2006/01/22(日) 22:49:30
だから禿禿言うなって何回も言ってるだろ! いい加減起こるぞほんとに
何が起こるんだろうか…もしや禿(ry
290 :
デフォルトの名無しさん :2006/01/23(月) 00:10:53
>>290 そんなこと言うとあなた、禿が起こりますよ。
禿の頭舐めたい
293 :
デフォルトの名無しさん :2006/01/23(月) 09:20:54
甘酸っぱいよ
プログラミング言語C++:第3版の「7.7関数ポインタ」とかは 四段ですが。別のところに載ってますか?
規格書読めや禿げ
(;`Д´)・・・・・
規格、お題目、並べ立てるやつは口先だけの場合が多い
「禿本読め、コンパイラのマニュアル読め、コード読め。」 これらは相談スレ的には酷すぎんか? 「入門書読め」ならわかるが。
>>301 そうだね、あんまり禿、禿、言うのはかわいそう。
303 :
デフォルトの名無しさん :2006/01/23(月) 20:00:59
>>301 禿本は我慢して読むだけの価値があると教えているわけだが?
使い方1つで原価の1万倍くらい当たる本だぞ
正直、禿本も読まないでコード書いてるようなヤシとは仕事したくない。 集中して読めば一週間で読了できるのに。理解が進むのはさらに後だとしても。
禿本を集中して一週間で読ませるようなヤツもどうかと思うがなw
読了しただけで意味あるような禿本なんてあったっけ?
>>300 なんだと、おれはちゃんと金もらうだけのことをやってるぞ!
308 :
デフォルトの名無しさん :2006/01/23(月) 21:37:13
禿本高杉
このスレがお笑いスレになっている件について。
もったいぶってる奴が多いな
C++の本で邦人の著者は柏原正三の一人勝ちなんじゃないかのお。
なにこのスレ
僕の禿本は湿気を吸ってなんだかペラペラになってます
2000にspecial editionなんてのが出てるけど、 あれは何か新しいことが書いてあるの?
>>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).」
を見落としている。まぁダウンロードできるものだが。
>>316 俺の禿本は持ちすぎて表紙が溶けかかってる
321 :
デフォルトの名無しさん :2006/01/25(水) 20:04:09
Cだとリスト構造を作るために、構造体に自分と同じ型のポインタの prevやnextといったメンバを持たせたりするけど、C++の場合は 全てvectorやlistで管理するんですか?
>>321 Cスタイルで書きたければCスタイルで書けばいい話じゃ?
323 :
デフォルトの名無しさん :2006/01/25(水) 20:23:33
>>321 まぁそういう便利なクラスライブラリがあるから、
自分でわざわざ作る必要はないけど、
特殊なデータの保持の仕方をしたければ
自分で作ればいいんじゃない?
けど基本的にSTLでできることはSTLでするってのが道理だろうな STLの奴は全部、ある程度以上のパフォーマンスを出せることが 保証されてるわけだし
自分で書くメリットがまったくない。 STLを使うと ・素晴らしいアルゴリズムの恩恵を受けられる ・STLは世界共通 ・例外安全 ・速い ・メモリ領域に関して無駄に悩む必要がなくなる 他にもいろいろあるだろう。 自分で直線的なリスト形式を実装するのは、 Chain Of Responsivilityのときくらい。
速いかどうかは微妙だなぁ。 カリカリにチューンするならSTLは使わないけど。
STL 多少の非効率はあるよね。 例えばリストなど、新規ノードの追加で必ずコピーコンストラクタが呼ばれる。 ポインタ型にすれば解決できるが、参照とサイズが無駄になる。
328 :
デフォルトの名無しさん :2006/01/25(水) 20:57:52
>>327 もうその辺は気にせず、boost::shared_ptr を食わせたりしてる。
マジでかりかりにチューンが必要な場合は、
スクラッチからコンテナを書くな。
最近コンテナ書いたのって、歯抜けを許すリングバッファかなぁ。
STLのスタイルがどうにも合わない
330 :
デフォルトの名無しさん :2006/01/25(水) 21:03:34
>>329 マンコをチンポに合わせるんじゃない。
チンポをマンコに合わせるんだ。
ネストしたクラスなんですが class A { private: typedef int Hoge; static Hoge aaa; public: class B { public: B() { Hoge i = A::aaa; } }; }; A::BがAのプライベートメンバにアクセスしても怒られないのですが これは暗黙に friend class B; が宣言されると解釈していいのでしょうか?
333 :
デフォルトの名無しさん :2006/01/26(木) 00:08:50
>>331 いや、おかしいと思うぜ
C++ の規格では ill-formed でも診断メッセージの出力は義務づけないとされているケースが多いから
もしかして・・・とは思うが、それは自分で調べれ
>>331 BはAのメンバなのだからAのprivateメンバにアクセスできて当然。
class Aの中に書いたものはネストしたクラスでも何でも全てAのメンバ。
メンバが static だからだろ
C++とフリーのDBでO/Rマッピングできるフリーのライブラリを教えて下さい。
>>335 class A
{
private:
int i;
public:
class B
{
public:
B()
{
A a;
a.i = 0;
}
};
};
なんてのも通りました。コンパイラはVC++2003です。
>>337 >A a;
>a.i = 0;
インスタンス化したらコンパイルされるのはあたりまえ。
>>331 defect report でアクセスできるように決まった。
そんなわけで古いコンパイラだとアクセスできない。
なんか今 open-std.org が見れないんではっきりソースは出せない。
確か、その手の内部クラスへ(から?)のアクセスが
BCC5.5.1とBCC5.6.4で変わってた覚えがあるから(どちらになったかは覚えてないが)
>>339 の言う通りに違いないだろう、と俺は思う。
あ、もっと古いバージョン(BCB4の奴)かもしれない。 まあとにかく、変わったって事で。
343 :
デフォルトの名無しさん :2006/01/27(金) 00:08:50
ちょ、おまえら、あのさ、名前空間を com::example::cvs::mylib::hoge とかにするのはどうよ??
namespace www::google::com;
::の代わりに . が使えたらよかったんだけどな。
>>344 逆じゃね?
可変長テンプレート引数って、どうやれば宣言できるの? tuple<int,int,double,double> tuple<char,char,int> みたいなクラスを自分で作りたいんだが。 いろんなところを調べると、 template<class T1,class T2,...,class TM> class tuple; みたいな書き方がされてるけど、当然のごとく このままではコンパイル通らないし…
boost::tupleのソースみれ
>>346 真に可変長のテンプレート引数なんてものはできない。
デフォルトのクラス指定があって省略可能なだけ。
>>348 なるほど。
可能な最大長で宣言されてて、デフォルト引数は無効を示す
型タグになってて、さらに無効な型タグによる特殊化をしてるんだね。
thx
>>343-345 名前空間をユニークにするために
標準的に使われている名前付け規則ってある?
351 :
デフォルトの名無しさん :2006/01/27(金) 08:38:09
>>325 C++ を純粋にオブジェクト指向言語としての恩恵を受けるだけのために
使いたいときに、STL や boost を使うともれなくジェネリックプログラミングの
世界に引きずり込まれてしまうのが何かイヤン。
テンプレートは分割コンパイルにも(メジャーなコンパイラは)対応してないし。
352 :
デフォルトの名無しさん :2006/01/27(金) 08:44:32
>>343 なんか Java に影響されすぎだなw
実際問題、名前空間って作者(制作会社)の名前(ニックネーム)や
ソフトの名前が多いと思うけど、適当に付けて被ることそんなにあるかいな。
>>352 まぁなぁ、名前空間に関してだけはマジでそう思うんだわ。
というか、インクルードパスと名前空間とを統合した
新しいインポート規則とか便利じゃね?
って、それもJavaに影響され杉とか言われそうだな。
実際、Javaをそれほど使ってる訳じゃないんだが、
どうしてもグローバルにユニークな、ってのに
こだわってしまうんだよな。
それはむしろXMLの名前空間からの影響かも。
354 :
デフォルトの名無しさん :2006/01/27(金) 08:54:36
Java のパッケージの場合は、プログラムをコンパイルしてユーザーがその プログラムを使うときまでクラスパス指定などでずっとついて回る問題だから、 世界規模でユニークというのを保証するのはまあ必要だと思う。 ただ C++ の場合は、一度コンパイル・リンクしてしまってネイティブコードに なったら、名前空間もへったくれもないからなあ。
だよな ソースレベルの共有ならリファクタリングブラウザさえあれば問題起きないし
>>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;
}
c++0x は俺が生きてるうちに出るんかなあ
c++0x は俺が生きてるうんち出るんかなあ
というよりいつまでC++0xなんて言ってんだ? 今年中に出せマヌケな禿め
>>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) {} とかやってみましたがエラーが出て終わりですよ!
A::A(T a, T b, T c) { array[0] = a; array[1] = b; array[2] = c; } ってやるしかないと思うよ。
早! サンクス!あきらめます!
>>361 指定する方法はない(論拠:禿本§10.4.7 クラスの配列)
class Aのコンストラクタの引数に配列を取るようにしたら?
>>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;
};
};
};
無名のunionってアリだっけ?
>>365 それってPODにしか使えないからあまり価値なくね?
いや、まあどうしても初期化したいのならこうしかないかなぁと。 無名共有体は独自拡張だから使いたくない代物であるのはわかってるけどね。
>>368 あれ? Cでは独自拡張だけど、
C++では言語仕様として認められてたはずだけど
横からで悪いがマジすか? 規格何ページあたりかわかります?
372 :
369 :2006/01/27(金) 17:44:25
>>370 規格書持ってないんでPDFの方を見たけど
JIS X3014
130ページの9.5.2 に記述されてた
うはwあった。マジでサンクス C++でも独自拡張かと思ってた
ついでにお願いできれば、 struct xxx { ... char name[0]; }; のような、末尾のメンバのサイズを0に出来るというのも、 Cだと独自拡張でC++だと標準だったような気がするんだけど どこかに載ってますかね?
そんなことが出来たとしてなんか役に立つの??
可変長構造体と呼ばれる、かなり有名(かつ邪道)なテクニック
ちらっとぐぐったら、 C99では、最後のメンバのサイズを0にするのではなく、 最後のメンバのサイズを省略できるらしいですね。 つまり、事実上ラベルとしてのみ使われるメンバを作れると。
VCでSTLのreverse_iteratorが reference operator[](diff_type Off) { return *(*this + Off); } と実装されてます。 これって一時オブジェクトの参照を返してるように見えるけど 合ってますか?
reference の定義を見ないとね、なんとも。
380 :
デフォルトの名無しさん :2006/01/27(金) 20:32:01
質問なんですが、CGIがすでにネットワーク上に用意されていて、 それを実行するためのコマンドもわかっていたら C++でCGIを呼び出す(?)ことは可能でしょうか?
>>378 間違ってる。単に一時オブジェクトのメンバ関数を呼んでいるだけ。
return (*this + Off).operator*();
>>381 ギャー、operator*(), operator+()を見直したらちゃんとメンバ変数の参照を返してました・・・
どうもありがとうございました。
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;を書けばいいと思うんですが… おねがいしまつ。
template <class T> friend class B;
387 :
384 :2006/01/27(金) 21:56:08
std::listなんですが、sortしてもイテレータが有効なのは保証されているのでしょうか? あと、どのコンテナがどんな操作をするとイテレータが無効になるか 書いてあるとこありませんでしょうか?
内容を破壊しないソートはstable_sort(だっけ?) とかあるからそういうのを使うか、 作業用にコピーして使うとかそんな感じになると思う。
そもそもstable_sortは、 ランダムアクセスイテレータを条件にしてるからlistに使えねーよw それに内容を破壊しないんじゃなくてstable_sortは安定したソート。
393 :
388 :2006/01/27(金) 22:46:12
>>392 ウホッ!いいドキュメント。早速ブックマークしました。
ありがとう
イテレーターの上書きがないとかそういうのじゃないのか?
stable_sortはマージソート。 並び替える要素の中に等価のものがあっても、 元の順番と変わらない。 quick_sortは安定ではないために、 並び替える要素の中に等価のものがあったら、 元の順番と同じとは限らない。
>>396 stable_sort がマージソートである保証はない.規定されてるのは安定であることと,
追加計算領域を使わない場合 O(n (log n)^2),追加計算領域を使う場合 O(n log n) であることだけ.
これを満たすマージ以外のソートには二分木ソートや,前処理付の不安定ソート群がある.
std::list::sort()はstableだったよな確か
というより何故listはstableがデフォなんだ C++的にはlistでも最も高速なやつを標準にして stableを別個で実装するのが普通だと思うのだが
ランダムアクセス出来ないデータ構造で もっとも速いsortがstableだっていうだけじゃねーの?
設計手法のアドバイスをください。 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の定義を強要させる仕組みはできるか アドバイスよろしくお願いします。
>>403 class Ikimono {
virtual int legs() =0;
};
class Tako : public Ikimono {
int legs() { return 8; }
};
class Neko : public Ikimono {
int legs() { return 4; }
};
「うまい設計」かどうかは別として後者は満たしてると思うけど
>>404 なるほど。
その手法思いついていたんだけど
Ikimonoをインスタンス化できなくなるのが嫌だなぁと思ってやらなかった。
でもあらためて出されてよく考えるとIkimonoをインスタンス化することなんてねーや。
ありがd
>>403 「何かもっとうまい」と言われてもわかんねーよ。
なにが不満なのか言ってもらわないと。
407 :
403 :2006/01/28(土) 01:58:02
>>406 いや、マジその通りでごめん。
コンパイル時に具体的なユニークナンバー(4とか8とか)を決定するのではなくて
実行時にダイナミックに設定する方法はないかなぁとぼんやり思って。
(今書いてるプログラムでは
>>404 で十分なんだけどね)
・実行時にクラス固有の値を設定することができる
・インスタンスを複数生成してもその値は1つでメモリに優しい
・templateを使うとどうなるのかな?
の3つが知りたい方法。
3つ目が馬鹿っぽいこと言ってるのはわかるけどtemplateって個人的に何か憧れるのよw
336ですが、 C++にはフリーのO/Rマッピングライブラリは無いんでしょうか? C++はDB扱うのにはむいてないですか?
>>408 言語の向き不向きの問題ではない。自分で作れば?
>>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;
411 :
403 :2006/01/28(土) 04:12:17
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; // これもエラー }
チミたち、C言語なんて使うのやめなさい。 Visual Studio 2005をつかいなさぁい!
Visual Studio 2005 で C 言語使ってますが何か??
415 :
デフォルトの名無しさん :2006/01/28(土) 09:15:37
>>412 メンバ関数へのポインタだろ?
void* や int にキャストって、もしかしてそいつが4バイトとかって前提で考えてるか?
>>415 がいうように、メンバ関数は4バイト以上になる事がありマス
>&px->func 2003だとC2276になるんだけど。
418 :
enumのスコープ(?) :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 ということでしょうか?
>>398 (STLの)stable_sortはマージソート
という意味
>>420 だから、そのSTLにおいてstable_sortがマージソートでなければいけないって規定はないでしょって話でないの?
規格と実装を(ry
>>412 標準C++ではできない。
普通はメンバへのポインタを使う。
ただ仮想関数のメンバへのポインタは気が利かせてあって、
きちんとポリモーフィズムが働く。
424 :
デフォルトの名無しさん :2006/01/28(土) 15:50:36
Visual C++で、coutで出てくるコンソール画面をもう一つ表示させて、 エラーを表示させるウィンドウと、処理結果を表示させるウィンドウの二つに分けたいんですけど そういうことは出来ないでしょうか? 簡単にウィンドウをもう一つ表示っていうのは難しいですかね? 初心者なんですみません。
>>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;}// デストラクタ };
>>428 C99ではdata[max]ってのは許容されてるが
C++でもよかったっけ?ダメだったと記憶してるが
素直にvector使え
っていうか、std::stack使え
>>428 -static int max;//ここがおかしいようです
+int max;
-int data[max];
+int *data;
432 :
デフォルトの名無しさん :2006/01/28(土) 16:59:57
クラス変数とメンバ変数とでは意味が全く異なってるんだが。 問題ないのかねえ。
ほんと低レベルなスレだな
またお前かw
>>434 まぁそりゃ他の高級言語と比べたら低級な言語だからね。
スレも低レベルな話題になるのは仕方がないだろう
437 :
デフォルトの名無しさん :2006/01/28(土) 23:04:39
>>436 メンバ関数へのポインタが void* に変換できない理由について
「低級な」説明ができないアフォがでかい面するところじゃねえよな
規格に照らして説明できないやつもでかい面してほしくないな。 4バイトとか、そういうの関係ないだろ。
440 :
デフォルトの名無しさん :2006/01/28(土) 23:37:23
自分は批判してないから辛くない
441 :
デフォルトの名無しさん :2006/01/28(土) 23:39:54
どう足掻いても defect なんたらで発言するに至りえないパラダイムを自慢したきゃ それをやめろと言える場じゃないんで静観するが俺に言わせりゃ(ry
442 :
デフォルトの名無しさん :2006/01/28(土) 23:42:22
間違いを恐れるな 何もしないで文句言ってる 真性のお馬鹿さんよりは1万倍マシ
クリリンのことかーーーーっ!!
例外、というかtryブロックのパフォーマンスについてです。 try{ hoge(); } で、hoge()が例外を投げずにreturnできる場合の実行速度は、 tryブロックが無い時と比べて目立って落ちるのでしょうか? もし囲むだけでも結構なコストがあるのなら、tryの乱発は避けて ある程度場所を吟味せねばいかんのかな、という事を考えております。
446 :
デフォルトの名無しさん :2006/01/29(日) 00:02:22
>>445 無理だよ
影響が大きくなりそうなテストパターンと
影響が小さそうなテストパターンが作れない者の
実験と称する無目的な奇行からは何も帰納できないよ
>>444 try で囲まなくても、デストラクタのあるローカルオブジェクトを作れば
巻き戻しのために try と同等のポイントができる。
ソースコード上に表れる try を避けるだけじゃ意味が無い。
で、ローカルオブジェクトの作成まで吟味してから決めるようだと
ほとんど本末転倒じゃないかな?
449 :
デフォルトの名無しさん :2006/01/29(日) 00:46:07
クラスについて質問なのですが class AAA { private: int a[10]; } のようなクラスがあったとして A aaa;と宣言します。 ここからaaaのポインタを取得してprivateで宣言されてる変数にアクセス することは可能ですか?
まぁ可能
>>449 #define private public
とすればいいやん。
453 :
デフォルトの名無しさん :2006/01/29(日) 01:22:09
>A aaa; undeclared identifier 'A'.
>>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
万策尽くせば可能かもしれないけど そんなこと自体考えてはいけない
スタイルの問題と言うか、設計の問題と言うか、 前々からどうすべきなのか悩んでいることがあるので 皆さんならどうするのか質問させてください。 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を変更するのが面倒だなあ、と。
458 :
457 :2006/01/29(日) 02:12:52
続き AやBやCを利用する側のクラスとかでまとめて定数を定義すれば いいのかもしれませんが、 利用者側がクラスの定数を定義しているというのは変な気がします。 A,B,Cで共通のヘッダファイルを読み込ませるしかないのかもしれませんが、 このaとかbとかは、それぞれのクラス固有の情報なので、 別のところに定数が設定されてるのもなんだかなあ、という気がしますし、 A,B,Cとか、全く関連のないもの同同士の情報が一箇所に集まってるのも どうかな、という気がします。 クラスの独立性を重視した場合、 A固有の情報である定数が、他の定数を定義してある部分と 同時に与えられるのはどうも気持ちが悪いというか。 A,B,C、みたいな書き方だと、なんかこいつら仲間みたいだから 一箇所で定義すればいいだろ、みたいに思えますが、 全く関連のないもの同士だと考えてください。 デフォルト値を一切しないで、利用する側で、適宜、 利用者側の定数(利用する側では、常にこの値を用いる)、 みたいなものを作る方法も考えましたが、 クラスA等を、複数の場面で利用する場合を考えると、 デフォルト値はあった方が便利な気がします。 すごく長くてすいません。
外部から取り込む仕様にすれば良いのでは?
>>457-458 難しい日本語でよくわからないが、たぶんそれはお前の都合でしか決められない。
461 :
デフォルトの名無しさん :2006/01/29(日) 02:19:22
>>458 俺もよく悩む。
結局ちらばってしまうか、
共通ヘッダで何とかするか、
しかおもいつかない。
もう一案 class A { public: A(int a = ::createDefault_a()) : a_(a) {} private: int a_; }; で、クライアント側で、必ず「::createDefault_a()」を実装させる
この有り難さが解らんのか・・・
>>457 の悩みは解決してると思うが
共通ヘッダでいいよ。 ちゃんとnamespace使ってれば。
466 :
457 :2006/01/29(日) 02:43:30
>>459-465 皆さんありがとうございます。
>>460 確かに自分でも、なんか無茶なことを言ってる気がしてきました。
自分がそのクラスをどう作りたいのか、によりますね。
>>462 それだと、AからZまでクラスがあったら、
クライアント側で26個関数を供給する必要があって
デフォルトどころか、逆に大変な気がします。
やっぱりうまい方法はないというか、無理な要求っぽいですね。
今後も悩み続けることにします…
>それだと、AからZまでクラスがあったら、 >クライアント側で26個関数を供給する必要があって >デフォルトどころか、逆に大変な気がします。 ・・・・・ そう言うもんな気がする >クラスA等を、複数の場面で利用する場合を考えると、 これがしたいのなら尚更
クライアント側に負荷掛けさせたくないのなら 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_; };
469 :
457 :2006/01/29(日) 03:22:42
>>467 確かに、
>>457-458 で言ってたことは、
設計上のトレードオフで相反する要求を
同時に克服しようとしている感じで、
要求自体が矛盾してるという感じですね。
>>468 利用される異なる場面で、それぞれ異なるデフォルト値を与えることができ、
そのデフォルト値を用いて引数なしのコンストラクタが呼び出せる
ということで、利点はあると思いますが、
もう一段階メタなデフォルトの概念ができるというか、
結局 class ZENBU は共通ヘッダファイルと同じことのような気がします。
>>457-458 は、はじめはデフォルト値は変更しないものとして
利用されることを想定して設計したものが、
その後、変更したくなってしまったために面倒なことになった、ってことで、
設計がおかしい、って結論な気がします。
>結局 class ZENBU は共通ヘッダファイルと同じことのような気がします。 同じなのは確か >もう一段階メタな それが狙い 唯、メソッドにしておくと、後々便利 プロパティファイルから取り込む変更とが楽 それから設計は、おかしくないと思う 実務っぽいAPLになってしまうけど
>>468 のメリットはクライアントが拡張したいときは
class NANIKA : ZENBU{
static int createDefault_a(){//これ以外は標準のまま
return 2;
}
};
みたいに拡張したい部分だけかけることだな。
まぁ殆ど書き換えるときは大して変わらないけど。
>457 単純に引数デフォルト値の悪用じゃね? デフォルト値を設定しなければ済む話じゃないの。
まぁ
>>457 が決めなさいってところか?
俺ならconfig.h作って#includeだけどコンパイルが糞重くなるよなぁ
474 :
デフォルトの名無しさん :2006/01/29(日) 12:07:17
>>473 config.h は autoconf がつかうからイヤン
autoconf自体がイヤン
476 :
デフォルトの名無しさん :2006/01/30(月) 00:45:00
vector型の変数eを先頭のデータから順に表示するにはどうすればいいですか?
>>476 一つのデータを表示する方法と、データを順に取り出す方法を組み合わせるといいよ。
>>476 copy + ostream_iterator
# 正直このくらいなら直にループ書いたほうが楽な気もするけどなー
>>476 1. ループを書く
2. for_each()にファンクタを渡す
3. boost::lambdaを使う
4. C++/CLIでfor each構文を使う
C++では無名関数が使えないので、
どれもぱっとしないのだが
480 :
デフォルトの名無しさん :2006/01/30(月) 01:15:18
std::copy( e.begin(), e.end(), std::ostream_iterator<int>(std::cout,"\n") );
482 :
デフォルトの名無しさん :2006/01/30(月) 07:52:13
C++にはなんでevalがないの?
>>482 欲しかったら自分で実装してね。
実行ファイルがいちいちインタプリタぶらさげる羽目になるけど。
そうでなくても共有ライブラリをうまく使えばましにはなるかもしれないね。
そうすると結局C++でなく他のインタプリタ言語を使っておけばよかったと後悔するわけだ。
>>482 C++ は静的な型チェックを厳重にすることで、実行時の安全性を提供
することを大切なものだと考えているから、eval なんて動的な翻訳系は
提供できないのさ。たとえ実行時の自由度が低下したとしても、安全の
ほうが優先されるのさ。
485 :
デフォルトの名無しさん :2006/01/30(月) 12:41:26
>>483-484 そんなこと言っておきながら、ホントはあったら嬉しいんでしょ?
まあ無名関数すらない現状じゃまだまだ先だろうけど。
>>484 evalと静的な型チェックって相反するものなの?
コンパイル型の処理系でevalがあって何がうれしいんだ?
>>485 コンパイラとインタプリタの違いから勉強しなさい。
488 :
デフォルトの名無しさん :2006/01/30(月) 13:20:14
ところで、ツールにスクリプティングの機能を持たせたいとき どんなインタプリタエンジンを組み込んだらいい? Tcl系、Lisp/Scheme系、FORTH系とかいろいろあるけど、 サイズが小さくてよさげなものはなんだろ。 お勧めあったら教えて。
組み込み用のインタプリタだとluaあたりが定番じゃないか?
> そんなこと言っておきながら、ホントはあったら嬉しいんでしょ? 全然
491 :
デフォルトの名無しさん :2006/01/30(月) 14:18:43
>>489 初めて聞いた。ブラジル産で、ポルトガル語で月、らしい。
それにしても
>>476 は一体どんな風にvectorを知ったんだろう。
普通STLのコンテナの解説にはforループのサンプルもついてくると思うが
493 :
デフォルトの名無しさん :2006/01/30(月) 18:33:28
読まない、調べない、考えない、これ常識。
例のゆとり世代と言うやつか
ついでに、プログラミングしない、で476は幸せになれるのになぁ
ループを一切使わないSTL原理主義者の書いた解説かも知れんぞ
今独習C++で独習中なのですが、何だかこの本でいいのか不安です。 もし↑読んだ方いたら、他の初心者用のと比べてどうかなど指摘して欲しいのですが。 お願いします。 //不安な点の例) 「アドレス情報を保存しなさい」という問題→ちゃんと「住所」と訳してくれないと紛らわしい('A`)
とりあえず「アドレス帳」に文句をつけときなさい。
C++で何やればいいの? メッセンジャーソフト作れる?
独習C++は読んだこと無いが、 独習JAVAはウンコだった。
>>497 そこは「アドレス」が通称なので気にしなくてよい。
>>501 失礼、言葉足らずでスマソ
俺もポインタのだと思って、ちゃんと作ってから答え見たら
「street」とか「city」とかの情報を文字列で保存してあったのですよ・・・('A`)
訳書なので、独習CはよかたのにC++はイマイチなのかな、と
//問題原文一部→「名前とアドレス情報を保存するクラスを作成しなさい。クラスの非公開メンバ〜〜desplay()というなまえを付けます)。」
>>500 C&C++書いた人と、Java書いた人は違うみたいでした。
Javaもいつかやるかもだから、気をつけてみます
確かに酷い そこは、純粋に俺の誤植ですよ・・・('A`) どうせもう買っちゃったわけだし、素直に全部読んでみます。 ありがとうございました
正直なところC++は入門書1冊読んだくらいではどうにもならないから どれでもいいと思う
おまいらはC++の本を何冊持ってるの?
1冊も持ってない
習うより慣れろだにょ
4冊。 どれも定番のみ
511 :
デフォルトの名無しさん :2006/01/31(火) 04:37:27
初心者です。コピーコンストラクタを引数をもつコンストラクタに 書き換えることは出来ますか?あるいは出来る場合と出来ない場合があるのでしょうか?
C++入門なら、高橋麻奈神のやさしいC++一冊+インターネットで十分だと思うよ 独習C++は激しく読みづらかった
なんでもいいから1つプログラミング言語知ってるなら最初から禿本でいいと思うが。 あれ、結構内容浅いし。カバーしてる範囲は広いが。
514 :
デフォルトの名無しさん :2006/01/31(火) 05:16:08
A級B型C++
>>511 コピーコンストラクタの引数は決まってる。変更不可。
むしろ、変更したらコピーコンストラクタじゃなくなる、ってのが正しいかな。
C++の本10冊あるが・・・ みんな以外と持ってない?
Effective C++ More Effective C++ Effective STL Modern C++ Design D&E この5冊があれば他にはいらない。
>>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++オタだと思うぞ.
(俺は研究上必要になったので揃えたんだが……)
>>519 俺は英語読めないヘタレだから、
More Exceptional C++とか、
訳が糞らしいってだけで敬遠してる
More Effective C++は持ってない・・・
でもやっぱり買おうかどうか迷ってる。
でも持ってるだけで、難解すぎて読めてない本とか、
これから読む予定で予定は未定な本が半分くらいだったり
PLCPP3rd D&E Boost 偏ってるなぁ俺……
>>520 More Exceptional C++の訳書って出てるの?
523 :
道化師 :2006/01/31(火) 08:28:42
>>517 JIS X 3014 や ISO/IEC 14882 の .pdf も数に含めていいですか?
...俺、初心者向けのも結構買ってたりするし数え方次第では20冊超えるかも。
>>519 `Д´)ノ ヲタ言うな!
あと、まだ上げられてないけど
国際規格<ISO> C++ライブラリ ハンドブック
...俺はこいつを地味に重宝してたりする。( ただし、オススメはしない。 )
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
本を一冊も持たず、知りたいことが出てきたら ネットと人に本を借りることでしのいでいる俺。 あと、一番役に立つのが自分が昔書いたコードだな。 しかしコードの全文検索って、ふつうの文書と同じように 全文検索してもうまく検索できないんだよな。 あとで検索することを考えたコメント書いておかないと。
in depth 全部
EffectiveとEfficentはなんか数回読むだけで十分な感じがしてしまう
529 :
デフォルトの名無しさん :2006/01/31(火) 17:19:30
JIS X3014 ↑ 規格票のくせにけっこう読みやすい
質問です。 hoge = (CHoge)hoge2; と hoge = CHoge(hoge2); は 同じものだと解釈しているのですが、この認識は正しいでしょうか。 可能であれば上の場合と、下の場合で呼ばれるコンストラクタを変えたいのですが…可能でしょうか?
>>530 その2つには違いがあると思います
前者はhoge2をCHoge型にキャストするので
((CHoge)hoge2)();と同様だと思う。コンストラクタではCHoge()が呼ばれる
後者はCHogeの引数を1つ取るコンストラクタが呼ばれる
>>531 > ((CHoge)hoge2)();と同様だと思う。
・・・いや、それは違うだろう。
>>531 お返事ありがとうございます。
ただ、引数をとるコンストラクタが呼ばれるようです。
今のところ両方とも
CHoge(const CHoge2& hoge);
が呼ばれます。
>>530 CHoge が hoge2 の型を取るコンストラクタを持ったクラス型なら、
どっちでも同じになりそう。
CHoge と hoge2 の意味に前提が無ければ、ちょっとだけ違うような気がする。
後者は static_cast<CHoge>(hoge2) と同じ。
前者は static_csat がダメでも const_cast, reinterpret_cast になるかもしれない。
>>530 試してみた結果、
hoge2 も CHoge 型だとすると
・(CHoge)hoge2 は何もしない。
・CHoge(hoge2) はコピーコンストラクタが呼ばれる。
hoge2 が CHoge 型ではないとすると
・(CHoge)hoge2 も CHoge(hoge2) も hoge2 の型を引数にとるコンストラクタが呼ばれる。
あとはどの場合も代入演算子のオーバーロード関数が呼ばれる。
(ノ∀`)アチャー やはり同じになってしまいますか。 JAVAの記述法をC++で再現という(意味の無い、C++の理解を深めるための)アソビをしておりまして。 DataInputStream型 と InputStream型を作ったのですが困っていたのです。 dis = (DataInputStream)is; とやれるように作った(ダウンキャストを再現)はいいのですが、DataInputStreamのコンストラクタには普通にInputStreamを引数にするものがあるのです。 (DataInputStream)で変換された場合は「そのまま内部ポインタをコピー」すればいいのですが、 InputStreamを普通に引数にとるコンストラクタなら「InputStreamに無くてDataInputStreamにあるデータの初期化」も必要となります。 これは手詰まりかな…。
なんて無駄かつ楽しそうなんだろうw
hoge2が operator CHoge &() なんて類のメンバ関数を持ってても違いはでないんだっけ? # コンストラクタに explicit の指定がないと曖昧だって言われてエラーになるような気もするけど。
質問です。 何もライブラリが利用できない環境でC++を利用したい場合(組み込みとかOS等) C++の言語の機能(ライブラリは除く)をフルに使うには何を実装すればよいかの 情報ってどこかにありませんか? 例えばnewやdeleteの中身は実装しないとC++は利用できないですよね。
540 :
デフォルトの名無しさん :2006/01/31(火) 21:56:23
>>539 規格書を読めば逆に何を実装しなければならないかと言うことは書いてある。
組み込みのような環境は自立処理系などと言う呼称で一部のライブラリだけ用意されていればよいことになっている。
>>540 組み込みで例外処理を独自に実装するのは、
よほどのチャレンジャーじゃない限り現実的じゃないぞ
543 :
デフォルトの名無しさん :2006/02/01(水) 01:22:57
標準関数って std 名前空間の下にあるんですよね? using namespace std; していなくても、 getchar() とか普通に使えるんですが・・・ もちろん std::getchar() でも使えるんですけど、 これじゃグローバルにあるのと変わらない気がします。 std 名前空間だけ特別扱い??
釣りなら釣りとメールr
(;゚д゚) ・・・ (つд⊂)ゴシゴシゴシ _, ._ (;゚ Д゚) …!?
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() が使えるんですが、
これは使用なんでしょうか?
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 を使っています。
>>549 それはね、C++の規格書のmissなんだよ。現在では修正されていたはずだけど。
むしろ、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
>>552 分かっているとは思うけど
cstdlibには標準入出力は定義されていない。
cstdioならグローバルな空間を汚染する。
>>549 の場合iostreamが暗黙的にcstdioをincludeしてるから可能だった。
あ、cstdioとcstdlibを読み違えてた。ていうか、なぁんで cstdioはglobalに放り込むかなぁ
555 :
553 :2006/02/01(水) 03:01:25
>>554 グローバル空間を汚染しない実装も可能だけど現実の問題として
C/C++両方のヘッダを弄るのが面倒なので
stdio.hはCのままで
cstdlibで
#include<stdio.h>
namespace{
using ::getchar;
using ::putchar;
......
}
こんな感じの実装をしてるのが原因だな。
ちなみにVC以外の他の多くのコンパイラでも同じような状況。
だからC言語の名前とだけは、
ぶつからないように定義しとかないと問題が発生しやすい。
何回やるんだよこのネタ。
>>556 「STLを使うと〜」のテンプレにみたいうまいことまとめてくれw
質問です。 int a[] = {0, 0, 0, 0}; のような {x, y, z}という初期化パラメータ記述は、独自クラスででも使えるのでしょうか? 使えるなら記述法を知りたいのです。
>>558 コンストラクタがなくて、メンバが全てパブリックなクラスなら使える。
560 :
デフォルトの名無しさん :2006/02/01(水) 17:44:21
561 :
デフォルトの名無しさん :2006/02/01(水) 19:26:35
文字列の簡単な解析をしているのですが,数値は数値として, 文字列は文字列としてVectorなどに格納したいと思っています. 現在はとりあえず全てstring型に変換してvector<string>へ格納し, そのつど数値かどうか判定し数値ならばatofなどで変換をしています. そのつど変換したり判定したりする部分がちょっとややこしいので できればそのまま格納してやりたいのですが何か良い方法はないでしょうか?
562 :
561 :2006/02/01(水) 19:28:51
>>561 の補足です
すいません,簡潔に言うと,同じ1つのvectorに
複数の異なる型を入れたいと思っています.
vector<???> v;
v.push_back(10);
v.push_back('*');
v.push_back(23.5);
565 :
561 :2006/02/01(水) 19:40:42
>>563-564 おお,便利そうですね.これで解決できそうです.
ありがとうございました.
なーんか設計見直したほうが最終的に良い予感がしてならないけどな (保守・教育双方の観点から) 細かい事情が分からないからあまり突っ込んだことは言えないが
567 :
561 :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
ん?ラムダブラザーズ?
ワンダバスタイル?
見えないブラザーが保護者のようにキミを見る
>>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 わーい、道化師さんだ〜!!
ほんの話題が出ているようなので、 便乗で質問しますが、 どういう風にクラスを作ればよいのか、とか、 継承や多重継承の有効な使い方を解説した本でお勧めはありませんか?
継承とか一通り解っているのなら 「オブジェクト指向のこころ」
「さ〜これからバリバリプログラミングの勉強するぞ〜」 っていう初心者に一番最初に教えるべき事は 「まず、プログラムを新しく書かずに済む方法を考えろ」
577 :
574 :2006/02/02(木) 00:36:26
>>575 一応、C++の文法は一通り書いて、覚えてみたのですが、
どういう風にクラスを書いてよいのか、思いつかないのです。
>>577 OOP的設計の仕方が分からんのか?
それなら憂鬱なryをお勧めする
わかりやすいし読んでて面白い
>>577 ちょいと(かなり?)背伸びするのなら
「アジャイル開発の奥義」
どうせならモダンなooの本を
クラスってのは手段であって、目的じゃない。 やりたいことを明確にすれば、どういうクラスを書けばいいかわかるよ。 あとはある程度の量をこなさないと駄目だね。とにかく書く。 そのうち「あ、そういうことか」という瞬間が訪れるよ。 ま、やってみなはれ。
高凝集度と疎結合が書いてある本が良い
>>574 オブジェクト指向本って、Javaを念頭において書かれてるのが多くて
やたら継承を多用してたり、仮想関数や動的解決に依存した
スタイルだったりするよな。
でも、C++はそれとは逆にテンプレートと静的解決の
ジェネリックプログラミングに向かってるから、
C++の勉強でOOP本を薦めるのは痛し痒しってとこだな。
583 :
574 :2006/02/02(木) 00:55:19
確かに、いまはC++ Template Metaprogrammingという本にハマっているのですが。 今まで敬遠してきたboostが、ものすごく面白いライブラリに思えています。 ただ、boostの実装方法は、さっぱり理解できません。 ソースを読んでもさっぱり。 使う分には、簡単なのですが。
言われてみれば、
>>575 はJAVAの本だったorz
クラス設計の観点からは同じな部分多いんだけど
boostの中身は魔法の呪文
さすがにboost::arrayあたりは簡単だぞ
今までなんでもかんでもオブジェクト指向で動的解決させてきたのが ジェネリックプログラミングで静的にも解決させたほうがいい場面もある、って流れだろ? 基本文法→オブジェクト指向→ジェネリックって流れがいいと思うけどなぁ
>>583 それ、読んでみたいけど、日本語版はまだないよね?
洋書でもいいんだけど、翻訳版が出そうな気がして手を出しづらい。
MPLの作者が本書いたのか。知らなかった。
std::string str; : const char* p = str.c_str(); strが変更や破棄されない限り、pが指す先が有効である事は保証されているのでしょうか? localtimeの様にバッファを共有していて、別オブジェクトのc_str()呼び出しで 内容が変わったりする実装があったりするんでしょうか?
boost::mplよりTypeListの実装の方がカッコいい
>>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メンバを呼ぶまでポインタは有効
ってことでいいんでしょうか?
>>594 21.3.6 basic_string string operations [lib.string.ops]
プログラムは配列に格納された値のいずれも変更しないものとする。
また、プログラムは、(c_str()の呼び出し時の)thisと同じオブジェクトを指す
basic_stringクラスの非constメンバ関数に対して、
その後のどんな呼び出しの後にも有効なポインタ値として戻り値を扱わないものとする。
→ 非constメンバ関数が呼び出された後は有効でなくなる。constメンバ関数については未定義。
>constメンバ関数については未定義。 マジっすか? 非constメンバ呼び出し→以前のc_str()で得たポインタは有効でなくなる そうでないなら(constメンバ呼び出しなど)→以前のc_str()で得たポインタは有効のまま と解釈できると思うんだけど。
そうえいば、以前 cppll だか、 vcppML だかで、実装によっては c_str() を使った インスタンスをコピーしたインスタンスが書き換えられただけで無効になってしまうとかで こんなんじゃ使いモンなるかー、ゴルァ(゚Д゚)って話を見た気がする・・・ 確か、エピたんがSTLのヘッダのどこそこのオプション弄ればこの問題を回避できるとかって 言ってたようなとこまでは覚えてるんだけど・・・ かなり曖昧な記憶なんで、俺の記憶違いかも知れん。
>>589 おそらくでないから。翻訳したところでマニアックな人にしか売れないから。
だから買おうね。
21.3.6以外にbasic_stringのc_str()に関する記述がなければ、未定義ということになる。 constメンバ呼び出しなら変わらないと期待できそうだけれど、 実装の仕方によっては変わることもあり得る(効率のために)。 毎回c_str()を呼び出すか、自分が使用するコンパイラの実装を確認するしかないんじゃないかな。
そこでvector<char>
つーか毎回c_str呼んでなんか不都合あるのか?
602 :
591 :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> とかか。
昔、自分自身は文字列を持たずに元文字列への参照を持つ部分文字列クラスとか考えたことあるな。
正直、マルチスレッドが普及した今、 std::basic_stringの、refcountを前提とした設計は、時代遅れ。 素直に毎回バイト列をコピーして、スレッド内でのconst性を 確保したほうがマシ。
短い文字列(短いといっても数100文字以下程度で多くの場合が該当)だと
deep copy + fast allocation + 短文字列最適化 で
スレッド安全な参照カウント実装での速度に十分到達できるか,
場合によっては outperform できるらしいですしね.
ここら辺の議論は GotW あるいは"More Exceptional C++" で
具体的な数字出して比較されています.
http://www.gotw.ca/publications/optimizations.htm suffix array のような使い方だと,空間的な効率も似たりよったりか,
場合によっては deep copy の方が高効率かも知れませんし.
ただ,スレッド安全性を前提にしなくて良い場合もあるでしょうし,その場合の
参照カウントは有意な高速化が望める可能性があるとは思いますけれど.
なんでthisは参照じゃなくてポインタになったんだろ-? 参照だったら「delete thisはしていんんですか?」「this=&rhsはしていんんですか?」問題なぞ発生しなかったろうに・・・
>>608 C++ではthisという仕組みが先に出来て、
参照という仕様が出たのはそれよりもずっと後だから。
その頃には参照なんてなかったのさ
ちょ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を期待していたのですが、私は何か間違っているでしょうか??
>>614 istreambuf_iteratorはInputIteratorであってForwardIteratorではないから、
イテレータのコピーを取ってそれらを同時に操作しようとしても
期待した結果にはならない。
>>614 InputIterator は、一度 dereference すると、その状態は保障されない。
InputIterator it = ...
InputIterator itDash = it;
bool a = ( *it == *itDash );
としたとき、a == true は保障されない。
>>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* を 適用できること自体がそもそも保証されていないです.
すみません. プログラミング言語 C++ 第3版を見ながら学習しているんですが, 等号演算子のオーバーライドで, class X { // ... const operator ==( X&, X& ); とするとコンパイルエラーになるんです. 「エラー E2080 cmem.cpp 74: 'CMem::operator ==(CMem &,CMem &)' は引数 1 つで宣言し なければならない」 なぜなんでしょうか…
きみは、X x,y,z;に対して、x.operator==( y,z )と呼びたいのかね?
620 :
618 :2006/02/03(金) 21:24:06
誤) class X { // ... const operator ==( X&, X& ); 正) class X { // ... const bool operator ==( X&, X& ); }
621 :
618 :2006/02/03(金) 21:26:30
> X x,y,z;に対して、x.operator==( y,z )と呼びたいのか すみません, もう少し詳しくお願いします.
それで分からないんだったらやめた方がいいと思う
>>621 ヒント:==は3項演算子ではない。
そういうことがやりたければ、クラスの外に出せばいい。
624 :
618 :2006/02/03(金) 21:39:00
クラスの外に出せばいいのか... 了解です.
625 :
618 :2006/02/03(金) 21:57:32
T1 operator @( T2 ) の T1 は, a @ b の a に当たるのではなくて, 演算子 @ が返す型だったということで解決.
おいおい
わかったからよしとしよう
CでいきなりK&Rが無理じゃないのと違ってC++でいきなり禿本はきっつい。
そう?
Effective C++はちょっと当たり前すぎる感じがしたな。 むしろMore Effective C++が勉強になった
631 :
592 :2006/02/05(日) 16:26:13
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が含まれます。 よろしくお願いします。
633 :
632 :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.
635 :
632 :2006/02/05(日) 22:07:56
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をインクルードするしかないのでしょうか。 解決法があれば教えてください。
>>636 面倒なのを厭わなければ、
class Item;
typedef std::list<Item> List;
という内容のitem_fwd.hを作って、item.hとItemの前方宣言が必要なファイルの両方からインクルードするという方法がある。
これって実装の問題? それとも規格でそうなってんの?
639 :
636 :2006/02/06(月) 06:49:40
>>636 ,637
不完全方を引数にした標準テンプレートのインスタンス化による効果は未定義。
というわけで、標準コンテナを使ってる限り、その形で前方宣言は無理。
class Item;
typedef std::list<Item*> List;
これなら大丈夫。
>>640 >不完全方を引数にした標準テンプレートのインスタンス化による効果は未定義。
未定義っつうかインスタンス化しようとしたところでコンパイルエラーになるのでは?
ちなみに637の内容はインスタンス化じゃないよね
642 :
640 :2006/02/07(火) 01:57:55
>>641 ふむ。 typedef では完全な定義は要らないのでインスタンス化は起こらなさそうだな。
ただ、規格中にはっきりとした記述が見当たらない。
未定義じゃなくてコンパイルエラーになってくれればいいんだけど、例えば
class T
{
public:
... // public interface
private:
class Impl;
std::auto_ptr<Impl> pimpl;
};
なんて pimpl の雛型を書くと、ほとんどの実装でコンパイルは通るが
厳密に規格と照らし合わせると未定義動作になる。
>>642 >ただ、規格中にはっきりとした記述が見当たらない。
これが正しいかどうかは検証が大変なので置いといて
>なんて pimpl の雛型を書くと、ほとんどの実装でコンパイルは通るが
>厳密に規格と照らし合わせると未定義動作になる。
Tのインスタンスを作ろうとするとT::Implの定義が必要でコンパイルエラーになる
インスタンスがないものは動作しようがないので(たぶん)未定義動作は起こらない
のでは?
>642 コンパイルエラーにならないのは、pimplがポインタ変数(ポインタのサイズ はポインタが指すオブジェクトのサイズに無関係)だからだろ? std::auto_ptr<Impl> pimpl; が Impl impl; だったらコンパイルエラーになる。Implの宣言が読み込まれていない (sizeof(Impl)が不明な)状態で、sizeof(T)はいくつ?
>>643 > Tのインスタンスを作ろうとするとT::Implの定義が必要でコンパイルエラーになる
それ、やってみて言ってる?エラーメッセージは?
手元のコンパイラ2つでは、両方とも警告しか出ない。
>>644 それはわかってる。
auto_ptr<Impl> がコンパイル通るのに、実際には
規格で許されていないのが今の問題。
一般に、C<T>をインスタンス化するためにTが完全な型である必要があるかどうかは
Cの実装に依存する。(インスタンス化した文脈と処理系にも依存したかもしれない)
だから、標準ライブラリのテンプレートに不完全な型を渡すと、
標準ライブラリの実装によってコンパイルの可否が左右される。
そこで、規格は、そういう実装依存のコードを避けるため、
標準ライブラリのテンプレートに不完全な型を渡すこと自体を禁止したのではないかと。
>>643 >Tのインスタンスを作ろうとするとT::Implの定義が必要でコンパイルエラーになる
g++3.4.2では警告だけ。
>>644 コンパイルエラーにならない原因はその通りだけど、
>>642 はエラーにならないこと自体を問題視してるんだと思われ。
>>645 訂正
>Tのインスタンスを作ろうとするとT::Implの定義が必要でコンパイルエラーになる
T::Implのインスタンスを作ろうとするとT::Implの定義が必要でコンパイルエラーになる
649 :
647 :2006/02/07(火) 03:30:13
ごめん。とてもかぶった。
>>647 >標準ライブラリのテンプレートに不完全な型を渡すこと自体を禁止したのではないかと。
禁止したの?
ソースを
>>648 それは当たり前。今回の問題とは関係ない。
>>650 表現がおかしかった。正確には
>>640 の
>不完全方を引数にした標準テンプレートのインスタンス化による効果は未定義。
のこと。
>>642 それ未定義動作を起こす可能性のあるソースって書ける?
642の例はインスタンス作ってないから動作しないよね
>>653 それなら "public interface" を空にしてインスタンスの生成を追加すれば十分。
>>654 class T
{
private:
class Impl;
std::auto_ptr<Impl> pimpl;
};
int main
{
T t;
}
これ未定義動作なの?
>>655 そういうこと。(コンパイル通るように微調整すれば)
結論としては、item.h をインクルード汁ってことか?
実際問題として、 Tのデストラクタ内でauto_ptrが delete p する必要があるでしょ。 で、この時に、Impl::~Impl()が実装されているのかどうか(呼び出すべきかどうか)が コンパイラには判断できない。 (Implが実はPODのデータオンリー場合は、delete演算子はoperator delete()を呼ぶだけ) で、多分(警告だけで済むってことは)、~Impl()を呼ばないコードを生成する。 ・・・と思うんだけど、違うかな。
「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; }
>「655が未定義動作を起こすかどうか」を分解すると
>以下の(1),(2),(3)がそれぞれ未定義動作を起こすかどうかに帰結すると思う
>>665 の問題は「標準ライブラリの」テンプレート限定だから、それは違うんじゃないか?
>>661 665は655の誤植として
それって「標準ライブラリの」テンプレートとその他のテンプレートで
振る舞いを変えるように規格で決められてるってこと?
それは不自然だと思うなぁ.
ソースがあるならよろしく
>>658 いや、だから、item.h をインクルードして、
Item の定義をちゃんとしておけば大丈夫なんじゃないの?
>>663 636の問いが
>item.hをインクルードするしかないのでしょうか。
だから663で問題が起こらなくとも636の答えにはなってない
でも>637は、ただ別名を定義しただけで、インスタンス化してる訳じゃない。 std::list<不完全型>自体を不完全型的に扱う限り、合法なんじゃないの。
typedefした時点でインスタンス化が行われるとか云う話を、昔に聞いたことがあった。 というわけで、#defineでよくね?
>>664 だから、「item.h をインクルードするしかない」という答えになるんじゃね?
>>667 #define しても、結局それを使う所で問題が起こると思われ。
ヘッダ内で使うと思うし。
>>668 664の時点では637と640が提案されていて
637が合法かどうかは議論中であるが
640の提案に異存のあるレスはない
従って「item.h をインクルードするしかない」という答えにはならないヨ
>>667 >typedefした時点でインスタンス化が行われるとか云う話を、昔に聞いたことがあった。
これも規格中にソースを欲しいですね(私も探してますけど)
637といい642といい結構私は常用してるのですが
あんまりみなさん議論に乗ってこないとこ見るとやらないのかな?
pimplが非合法なんて影響でかいと思うのですが...
pimplしたいならboost::shared_ptr使えば良いじゃない。 これは不完全型でも大丈夫だから
>>670 ソースみたらboostのsmart_ptrは対策をしてあるようですね
pimplだったらscoped_ptrの方がいいのかな
>>669 17.4.3.6/2 は標準ライブラリの話だよね。
おれは大体 pimpl に scoped_ptr 使うからどーでもいい。
std::tr1::shared_ptr は問題が起こらないだろうけど、 標準ライブラリだから不完全型を使うと非合法になるのだろうか。
674 :
デフォルトの名無しさん :2006/02/07(火) 16:14:19
いずれは boost:: じゃなくなりまするのか?
>>669 >640の提案が>636の欲しかったものだとは思わないな。完全に違う実装だろこれ
でも正直、厳密な規格だのライブラリの実装だのを気にするくらいなら
不完全型を使うの控えて>640にするか素直に全部インクルードするな俺は
676 :
デフォルトの名無しさん :2006/02/07(火) 20:21:51
std::string s; std::cin >> s; って具合に次々に文字列を読み込んでいくと、 確かに空白で区切られて読み込まれるんだけど、 改行した、ってのは認識できないですよね? std::cin.peek() == '\n' とかで判定するんですか?
ええ、あなた程度でも思いつくような事はさすがにやってます^^;;
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; これはエラーが出るのは何故?
a_type**だから。
a_type (*p)[5]=ob;
684も未だにポインタが判らない人。
>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 ってでちゃう。
intじゃないから…… それは型じゃなくて値
690 :
688 :2006/02/07(火) 23:13:19
>>689 ありがとう。
int 型の値 n が渡せて何で Point 型の値 n が渡せないの?
691 :
デフォルトの名無しさん :2006/02/07(火) 23:15:31
規格票くらい自分で何とかしろ タダで閲覧できるところまである
>690 そういう規格としか。 intとかboolとかの整数系はOKだけど、floatとか構造体とかアウト。 ポインタはどうだっけ?
>>690 リンカに Point 型の値を処理させるのは、とても大変で、
任意のユーザー定義型まで考えるとほとんど不可能だから。
694 :
デフォルトの名無しさん :2006/02/07(火) 23:32:07
リンカとかは後付け設定だな そもそも 688 の意図が単にコンパイラを困らせるだけのように見える # 後付け設定の権化が規格だったりもするが
696 :
688 :2006/02/07(火) 23:38:41
>>692 ,693
ありがとう。駄目なんだね。
組み込みの整数型だけは渡せるようなナゾ仕様になってしまったのかはわからんが。
便利じゃね?
Point p1, p2;
length = getLength<float, p1,p2>();
とか書けたら。
それにしてもtemplateを勉強するのに良い本はない。
>>696 それは
template <typename T> float getLength(T t1, T t2) {
return t2 - t1;
}
こうする事で int t = getLength<int>(5,8); などと書けるので
Point型に対した処理がしたいなら特殊化したテンプレートを書けば良いと思います
つーかユーザー定義型の使用を認めたらただでさえ難解なtemplateが 可読性0の埋め込み型スクリプト言語になっちまうぞ。
template<class T, Point& n> template<class T, Point* n> これならいける。
>>701 最適化されたとしても引数が定数でないことに変わりはないから、他のテンプレートに渡したりはできないわな。
>>696 が何をやろうとしているのか分からんが。
template< typename Key, typename Value > void foo( map<Key, Value>& in ) { map<Key , Value>::iterator it; } これをコンパイルするとエラーになるんですが、 正しくはどう書けばいいんでしょうか?
GCC だと typename map<Key, Value>::iterator it; とする必要がある。 でも、コンパイラによっては typename を入れた方がエラーになる。 #if defined(__GNUC__) #define TYPENAME typename #else #define TYPENAME #endif とかやっといて、 TYPENAME map<Key, Value>::iterator it; とするが吉。
>>705 まさにgccでした。ありがとうございます。
>>705 これって、規格的には typename 入れるのと入れないのと、
どっちの方が正しいのかな?
何か時代によって変わってそうな気もするけど。
mapが特殊化されていてiteratorは定義されていなかったりする可能性があるから
なるほど。 「typename はテンプレート仮引数にしか使えません」 とかエラー出るコンパイラは、まだ準拠できてないってことか。
typenameって、「これは型名ですよ」とコンパイラに教える意味も
持ってるんじゃなかった?
(classの先行宣言と一緒=以前はclassで代用してたのかも)
とすれば、
>>704 の例だと
typename map<Key , Value>::iterator; // 先行宣言
map<Key , Value>::iterator it;
なら、どんなコンパイラでも(typenameというキーワードをサポートしていれば)
通りそうな気がするんだけど。
試してないけどね。
あ、でも、エラーが
>>710 だとしたら、絶対無理か。
>>711 それはまったくのガセネタだな。どこで仕入れてきたんだ?
>>714 は?そこの解説には >711 のような内容は書いてないぞ。
typename が宣言を作るわけじゃない。
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 したときの型で渡さないといけないということですよね? # できればキャストせずにうまく動いて欲しいのですが
new-deleteとnew[]-delete[]の対応は神聖不可侵。犯すべからず。 あとvoid*ではdeleteできません。 どのデストラクタ呼んでいいのか判らんでしょう。 // 技術的な可能不可能の話で言えば、vtbl持ってるクラスのインスタンスならvoid*でもdeleteできそうだけど、 // void*ポインタからvtbl持ってるか判別はできないのでやっぱり無理。
719 :
デフォルトの名無しさん :2006/02/08(水) 09:07:01
強制的なポインタのキャストはやらない方がいいよね、安全面から。 ってそれを言語使用として禁止してしまわないのがC++のいいところ何だが。 なんでそんなことをしたいのか分からないけど、 もしいろんな型のオブジェクトを一手に扱いたい、なんてことであれば 一つの基底クラスから全部派生させるようにして 仮想デストラクタを使うようにするのがオブジェクト指向的だと思われ。 まぁ Java でいうところの Object クラスみたいなもん。 (C# だとどうなんだったっけ?)
720 :
717 :2006/02/08(水) 09:24:48
>>718 わかった。ありがとう。
でも、void* の delete の話を技術的に解決する話なら、new したときに獲得メモリブロックのヘッダにデストラクタのポインタか
vtblのオフセットかを記録しておけば、delete に渡されたときの型によらず適切なデストラクタを呼び出すことができそうじゃない?
いや、そういう仕様になってないんだから文句も無いけど。
>>719 char[] を獲得して void* に代入して、そのまま delete してるソースがあったから、気になって聞いてみた。
規定クラスの話は、自分で新規に作るなら多分そうします。
ありがとう。
全てのオブジェクト派生元となる基底クラスに ... virtual void Suicide() { delete this; } ってな仮想関数を用意して、 pObj->Suicide(); とでもすれば?
>>721 それ、 virtual デストラクタ+普通の delete に比べて、何がメリットなの?
>>721 仮想デストラクタじゃだめなの??
って書こうと思ったらすでに書かれてた。
はじめまして 本日から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の呼び出し関数の引数と戻り値に 構造体を使用したいのです。 よろしくお願いします。
こういうのがプロなのか ネットを何だと思ってるのかな
これは釣りだろ
727 :
デフォルトの名無しさん :2006/02/08(水) 17:21:54
int i; std::cin >> i ; として数値を読み込んでいます。 もし入力されたモノが数値としてふさわしくない文字列だった場合、 そのことを知るにはどういう方法があるのでしょうか?
if(!(std::cin>>i)){ ふさわしくない時 }
730 :
デフォルトの名無しさん :2006/02/08(水) 17:41:12
>>728 ありがとうございます。
つまり、istream::fail() ということですね。
>>720 メモリ空間を圧迫するから採用されなかったんじゃないかな。
たとえば、メンバがポインタ変数一つしかないようなクラスを考えると
デストラクタのポインタが増えることで実質倍のメモリを消費する。
そもそも、そういうことはポリモーフィズムで解決するのが C++ 流。 そういう場合に void* を使った時点で設計ミス扱いされても文句は言えない。
>>731 でもnewで割当てられたメモリブロックには元々メモリ管理情報が付加されてるから、ポインタ一つくらい増えても問題はないんじゃないかと思わなくも無い。
この辺は処理系依存と呼ばれる部分だろうけど。
>>720 やろうと思えば、その通りのことがユーザコーディングでできてしまうのが C++ 。
>>717 newして得たポインタを保持するのにboost::shared_ptr<void>を使えばよい。
boost::shared_ptrは自身のコンストラクタへの引数に与えられた型を保存しておいて、
その型でdeleteを呼んでくれるから、元の型のデストラクタが呼ばれる。
初心者的な質問でもうしわけないですが 構造体をファイルで管理するのはどうすればいいのですか? 構造体のメンバも一つずつファイルに書きこまにと駄目なですか?? 構造体名だけを保存してたんですが、いざメンバを使おうとしたら 読み込んでも使えない・・・・・・なにかヒントくださいTT
構造体名だけを保存の意味がわからん。プログラミング言語であらわせ
>>736 なにベースでコード書いてる?
Win32API? Cの標準関数? C++のストリーム系?
Boost.Serializationなんて言ってみる。
>>736 構造体を new するとき、ファイルを open
構造体からメンバを get するとき、ファイルから read
構造体にメンバを set するとき、ファイルから write
構造体を delete するとき、ファイルを close
する関数を作れば ok
const参照についてなんですが、 class foo { T hoge_; public: const T& hoge1; // <--(a) T const& hoge2; // <--(b) foo(): hoge1(hoge_),hoge2(hoge_) {} }; 上の(a)と(b)の書き方で何か意味の違いがあるのでしょうか?
>> 741 ない。
744 :
デフォルトの名無しさん :2006/02/08(水) 23:35:00
& const の意味が聞きたかったんちゃうのか?
& constなどない。
質問です。 java では引数とメンバ変数がかぶっていても、メンバ変数の方を "this.foo"とするようにしておけば特に問題ない。 1.C++ でも this ポインタを使えば同じことができるでしょうか? (g++ では問題なかった) 2.(上がOKの場合のみ) C++ で this->hoge = foo; って書くと変?
747 :
746 :2006/02/09(木) 00:09:55
> 2.(上がOKの場合のみ) C++ で this->hoge = foo; って書くと変? 2.(上がOKの場合のみ) C++ で this->foo = foo; って書くと変? の間違いでした…
でも、そんなことをするのは馬鹿しかいない。
751 :
746 :2006/02/09(木) 01:55:41
ありがとうございます
>>748-750 メンバ変数の方の頭や後ろに _ をつけたり m_ をつけて
this をはずせば馬鹿じゃないんでしょうか
>>750
>>751 名前が被ること自体が問題。
あえてリスクを負うようなコーディングスタイルは避けるのが
普通以上のレベルのプログラマの常識。
ただ、例外として問題が少々あろうが後腐れの無いプログラムで
そーゆー類のことをするのは全然構わんと思う。・・・逆にそーゆー
融通が利かすことができないのは一流気取りの三流プログラマ。
>>752 名前が本質的に同じであるのが自然である場合、
あなたは、どういう醜い名前の付け方をするんですか?
class date{
int year;
........
public:
........
void set_year(int year){
this->year = year;
}
};
>>752 setterでは普通に使ってるけど、やめた方がいいんだろうか…
void setHoge(type hoge) {this->hoge = hoge;}
>>753 g_ だの m_ だのといったプレフィックスを見たこともない人ですか?
自分のスタイルを押し付けるような気は毛頭ないがなんらかの方法で
名前が完全に被るようなことは極力避けるのが普通だぞ。
>>754 俺はそのケースでも引数にプリフィックスを付けて
名前の重複を避けるようにしてるけど
このケースは許容範囲なんじゃない?
てか、よくよく考えたらプレフィックス付けるほうが this-> を 使わなくても済むから結果的に表記もすっきりするね。 void setHoge(type hoge) {this->hoge = hoge;} ↓ void setHoge(type a_hoge) {hoge = a_hoge;}
758 :
753 :2006/02/09(木) 03:07:56
>>755 えーと、変数に無駄な接頭語付ける文化ってまだ存在してたんですね。
自分の場合ハンガリアンが駄目絶対と言われてたのを、
目にしてたので死滅したものかと思っていました。
個人的には、グローバル変数はg_hoge,メンバ変数はm_hogeとかするくらいなら
::hoge,this->hogeと書けば、
言語レベルでそのスコープにアクセスしていると保障が得られるので
素直に言語の機能を使ってました。
なのでスコープを明示的に指定できるC++で、
変数名にスコープ情報を入れたり無駄な接頭語を付けるのは、
気持ち悪いし美しくないなぁ、と思っています。
必要に応じて this-> 付ける場合、 this-> 忘れるバグを埋め込む可能性を恐れるよりは、 m_ つけた方がよっぽどいい。 明らかに異なる名前なら、間違える可能性がグンと減る。 毎回 this-> つけるなら別だが、長ったらしい。
>>758 「プリフィックス」と「ハンガリアン」を混同してる人ってまだ存在してたんですね。
MSもハンガリアンを推奨しなくなったんで死滅したものかと思っていました。
個人的には、所謂 getter に名詞を使うので、メンバ変数に m_ つけないと
被ってどうしようもなくなります。この衝突は this-> とかじゃ逃げれませんし。
761 :
754 :2006/02/09(木) 04:00:12
>>757 引数にプリフィクスを付ける手もあるのか、なるほど。
自分はメンバ変数をhoge_としています。
>>759 個人的には
void setHoge(type hoge) {this->hoge = hoge;}
は見やすくて好きなんだが、
バグのとこを考えると避けた方がいいように思えてきた。
762 :
753 :2006/02/09(木) 04:03:31
>>760 変な接頭語付ける文化は興味が無くて、
その手の文化はハンガリアンしか聞いたことが無いので勘違いしておりました。
確かにメソッドと変数名の衝突は頭が痛くなる問題ですね。
自分の場合getterにはget_hogeのような2単語で構成するのが殆どなので、
変数とメソッドの衝突は未経験ですが、
それを考慮すると奇妙な名前を付けるのも仕方がないのでしょうね。
今まで奇妙な接頭語を付ける人の気持ちを理解できなかったのですが、
理解はできました。
ありがとうございます。
Ruby の @ を付ければメンバ変数という仕様が C++ でも欲しくなってくるなぁ。
#define @ this-> 無理か
せめてthisが参照になればなあ operator[]とかポインタじゃ呼び出しにくい
this[0]["hoge"]
>>763 個人的に、そういう仕様はあまり好きになれない。
768 :
デフォルトの名無しさん :2006/02/09(木) 06:22:22
769 :
◆Uy3UpqU1oc :2006/02/09(木) 07:11:41
初めて書き込みますが相談があります。m(__)m 書き込みや読み込み先のファイルの、場所の指定はできないんですかね?
朝から釣りかよ
>>765 C++にthisが入ったのが、参照が入ったのより前だからごめん、
って禿がゆってた。
772 :
◆Uy3UpqU1oc :2006/02/09(木) 07:50:18
釣りではないんですが…orz
キリンさんの首輪はどこに付けたらいいの?
774 :
デフォルトの名無しさん :2006/02/09(木) 09:20:31
標準ストリームで、整数を 1234567 という形式ではなく 1,234,567 という形式で出力させる事はできますか?
適切なlocaleを与えれば可能。例としてVC++7.1で。 locale loc("jpn"); cout.imbue(loc); cout << 1234567 << endl;
776 :
◆Uy3UpqU1oc :2006/02/09(木) 10:23:30
すみませんでしたm(__;)m 自分であっちこっち移動させました…
Cの時の癖でそのまんまハンガリアンしてる俺って 就職したら迫害されるんだろうか
>>777 コーディング既約で一応変数名についてはそれなりの基準を示すから
現場では適宜それにしたがってくれればいいよ.
>>769 Windowsユーザと邪推すると、ディレクトリ記号「\」はエスケープシーケンスで使われるので
ifstream fin("C:\\Documents and Settings\\Gates\\testament.txt");
というように「\\」と重ねなければならない。
もしこれで正答なら漏れエスパー。
識別子 : 英字はすべて小文字、単語の区切りは下線 メンバ変数 : 下線を最初につける 引数 : 下線を最後につける、主となる引数を下線だけにする 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 = _; } };
>>780 先頭の文字がアンダーバーなのは、
C++の処理系に大域名として予約されているから余り好きじゃないなぁ。
大域名にマクロ使われるかもしれんし。
>>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;
}
>>780 ルールを覚えるのが面倒だから面罵も下駄も雪駄も同じ名前でいいよ。
class X {
int width;
public:
X(const int& width) : width(width) {}
int width() const { return width; }
void width(const int& _) {width = _;}
};
俺はm_派。アンダーバー一つだと普通に間違えそうで怖い あとgetterが素の名前()ってのはSTLでも使われてるけど パブリック変数なのかゲッター関数なのか紛らわしくないか? STLとか自分で書いたライブラリならまず間違えないし 間違えたとしてもコンパイルエラーで済むって言われたらそれまでだが
>>784 パブリック変数を使わず、必ずgetterを書くようにすることで統一を。
コンパイラが最適化のチャンスを見逃したら悲惨なことになるけどw
型名を接頭子にするのはどうしても慣れないなあ。
std::map<std::string, std::vector<std::pair<std::string, std::string> > >** p;
とかってハンガリアン記法で書くとどう書くの?
omanko
可能な限り、標準に近い形でライブラリは記述 クラスメンバには、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; };
M$製のSDKのサンプルみたいなm_pNextFrame みたいな長くて堅苦しいのが好きだから STLのコードが読みにくくてしょうがない
みたいなが連続した俺文盲
C++0xには@文字列付かんの? @"c:\Documents and Settings\Gates\testament.txt"); みたいなC#モドキにしてくれぇ。
>>790 Windowsは意外と大抵/を受け付けてくれるよ。
たまに\しか受け付けないものもあるけど。
>>791 dクス。UNIXがセパレータに'/'を使っていたので、ビル・ゲイツがひねくれて
わざとバック・スラッシュ文字を使ったような事は聞いた事があるけど、'/'も
使える場合があるのか。試してみる。
>>792 いや、単にCP/Mが/をコマンドラインスイッチに使用してたんで互換性の都合上/が使えなかっただけらしいが。
>793 そうだね MS-DOS = (CP/M + UNIX) / 3 だから
/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_・・は好きになれない 美しくない・汚い・見るに耐えない (慣れの問題だとは思うが・・) 抽象化が進むと、変数名命・メソッド名命 に、なって来るから余計そう思う
>>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 変数のようなもので
これは、全然違う希ガス
メンバ変数は関数で言うならグローバル変数のようなもの。 クラスのどこからでもアクセスできて、 メンバ関数を抜けても値が保存される。
m_が汚く見えるのは多分_Tyとかかなり短く略した命名してる人だろうな。
808 :
デフォルトの名無しさん :2006/02/11(土) 01:22:23
>>806 privateとpublicは、今の話には関係無い
>>807 長い変数名に、m_付ける方が汚く見える気がする
それ自体で意味成しているのに
それに余分な、m_付けるのはかなり気になる
最近のマイブームは int member(); void member( int value ); int member_; しかしスレ違いな気が……
>>808 >privateとpublicは、今の話には関係無い
privateメンバ変数の名前はインターフェースに含まれないから、
適当に名前を割り当てても良い、というのが
>>802 の意見だろ。
811 :
デフォルトの名無しさん :2006/02/11(土) 02:31:35
>>809 メンバ変数の最後に「_」付けるのは、目立たなくて控えめで個人的には好き
>>810 なるほど・・・そう言う意味ならば、
>>802 は、余計拙いと思う
メンバ変数は、
>>805 も言っている通り、グローバル変数的意味合いが強くなりやすい
(「1クラス=1責務」の原則を知らない人が多い現状では尚更)
ので・・・
ってか、public変数使う機会って、ほとんど無い・・と思う
少なくとも自分は1年以上使ったこと無い
813 :
デフォルトの名無しさん :2006/02/11(土) 02:56:28
単に勝手に好きな事言い合ってるだけだから良いんでないかい? 変数名・関数名の選定って、一番重要って説もあるくらいだし。
と、当事者は申しております
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が実行される
1. 継承でなんとかする設計にする 2. メンバ関数ポインタ(void (hoge::*)())を使う どっちにするかは状況次第。
templateってのもあるな。
それで解決できる状況なら、 普通にオーバーロードで解決できるんじゃ・・・。
>>816 hとhhが同じ型でなくてよいならtemplateで解決(MC++D参照)
同じ型ならば
>>817 の案をセレクト。
switch-caseで分岐する方法が……
/ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ | switch-caseで分岐って聞こえたような気がする!! \_______ ____________ ∨ | | / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ / ____ / | 19:00 |  ̄ ̄ ̄ _______ / _ / ,__ ∧∧ガバッ! () / iii■ ( ;゚Д゚)ミ  ̄/ /\∪ ∪ ̄\/ ∫∫ / ※⌒⌒⌒⌒/ ∫∫ / ※※※※ / ⊂⊃ / ※※※※ / ┗━┛ (______,,ノ
何!switch - case だと!!
こうしちゃおれん
別に本当にswitch-caseでも問題ない気が
>>825 何らかの理由で出来ないのでしょう。
hogeのコンストラクタで関数をチョイスしていることから推測
class A { private: public: }; と書いています。しかし先輩から、お前のは見にくいから止めろと言われました。 class A { public: private: } どっちが普通なんですか?
>>827 プログラムに限らずテキストを書くときには
人に見てもらいたいところを先に書いたほうがいい、
というのはわかる?
「これは基本的にあなたは知らなくてもいいんですが
・・・
・・・
おっとここまで書いたところは気にしないで下さいね。
いつ内容が変更されるかわかりませんよ。
さて、結局のところは
・・・
・・・。」
こんな文章読まされたら嫌だと思わない?
どっちでも良い。 単なる糞くだらない宗教問題だから気にするな。 ただ、もしコーディング規約とかで、 定められているのならそちらを使えばいい。 規約が無いのなら自分で良いと思うほうを使えばいい
立場によってprivateとpublicどっちをよく見るかは変わるだろ まぁそれでもpublicが先のコードが多いけどな
>>828 本当にメンバ変数を隠蔽したいならPimplを使うべき。
classには「何も指定されてないものはprivateである」という
明確な仕様があるから、それに従って
class A
{
ここにprivateなものを定義
public:
ここのpublicなものを定義
};
こう書いてるよ。
一番悪いのは、メンバ関数の定義とメンバ変数の定義が
ごっちゃになってたり、staticなメンバとそうでないのが
混ぜこぜになってたりすること。
>>827 先輩がなんで見にくいのか俺にはわからん。
メンバ変数の宣言が上下どちらかに統一されて
メンバ変数の初期化の順序が守られていればどっちだっていいよ。
それよりもクラスに対しての適切なコメントがないのが嫌。
>>832 pimpl にはオーバーヘッドとコードの増加が伴うので、
それが許容できる場面でなければ使えない。
class の暗黙の private を省略するのは、
演算子の優先順位に依存してカッコを省略するのと
同じぐらいウザイと思う。
明確な仕様というが、デフォルトで private になっている理由は
そんなに明らかではないだろう?
このレベルの話だったら、一貫性やコメントのほうがずっと大切だと思う。
>>834 「デフォルトではprivateである」という事実は十分一般的なんだから問題ないと思うが…
837 :
816 :2006/02/11(土) 16:33:16
ありがとうございます メンバ関数ポインタを使用します
>>834 >pimpl にはオーバーヘッドとコードの増加が伴うので、
>それが許容できる場面でなければ使えない。
許容できる場面の方が多いのでオイラはディフォルトはpimplにしてるな
最適化する段階でプロファイルしてクリティカルなものをメンバ変数にするようにしてる
>>836 public:が先頭に来るスタイルも多いんだから
見間違える可能性は小さくないだろ
>>836 演算子の優先順位に依存してカッコを省略する人ですか?
コーディングスタイルとして規定されて統一されてればどっちでもいい
>>840 依存せずに括弧を書く人ですか?
((((A+B)+C)+D)+E)
全く、括弧を省略するとは信じられないな。 1つたりとも無駄な括弧などないのに。 (- (+ 1 (* 2 (+ 4 6)) (/ 4 2)) 2) 21
MLで括弧を省略するとカッコいいな
lisperは黙れw # いや俺はlisp大好きよ
みっともない
>>842 その式は演算子の優先順位に依存していないから、
省略しても問題ないと言えるんじゃね?
classの暗黙のprivateに期待するのが悪いのなら、 当然ながらstructの暗黙のpulicにも期待しないんだろうな? struct Point { public: int x, y; }; 当然、わざわざpublicを書いてると。 限りなくウザス まさか「structの暗黙のpublicだけは信じる」とか言わんよな?
見間違えるかどうかは微妙だなぁ。 private:を省略するスタイルも一般的ではあるから見れば分かるし、 直後に連続して「public:」が続いていたら、不自然に感じるから問題はない気がする。 そもそも、メンバ変数をpublicにする状況というのも頻繁にあるわけじゃないしね。
structは暗黙でpublic、classは暗黙でprivateって 明確に仕様で決まってるから、structとclassの違いに意味がある。 いちいち冗長なpublicやprivateを書く方がムダ。
>デフォルトで private になっている理由は >そんなに明らかではないだろう? ARMにははっきり書いてあるし、仕様書は見てないが書いてあるだろう。 D&Eにも、C with Classesの最初期から「デフォルトはprivate」と はっきり意識していたと書いてある。 Javaみたいな言語と違って、C++の場合は「sizeof(class)」が重要な 意味を持つから、クラスのサイズを規定するものは一番最初に 書いた方がいい。その方が絶対にバグを減らせる。
ここまで話進んでるとは思わなかったよ、、、 今やっと半分ぐらい書き直したところ。
宗教論争をしてる奴ってそれが意味のある議論だと信じて疑わないんだなホント
>>828 pimplを使わない限り、classのprivate部分の変化は
そのclassを使っている全てのコードのリコンパイルを要求する。
Javaじゃないんだから「private部分はクラスのユーザーには無関係」
と言い切ることはできないのさ。
本当にprivateを意識させたくなければpimplを使うのが筋。
実装がFixしていてprivate部分に変化が無くなったら、
publicインターフェイスドキュメントを充実させればいい。
その方がよっぽど役に立つ。
struct の暗黙の public は直感的。 この仕様によって C と互換性を保っていることが簡単に推測できる。 全部 private だったら friend つけない限り意味無いし。 class の暗黙の private は、この仕様に決めた理由を知らないし、 推測することができない。 俺が無知なだけ?
856 :
828 :2006/02/11(土) 17:22:13
>>854 そんなのは知ってるよ。
でも public を先に書いたほうが良いのに変わりは無いよ。
>>855 お前が無知なだけ
classというキーワードを作ったそもそもの目的は、
「外部からのフィールドのアクセスが禁止されたstruct」
を作りたかったから。
考古学乙
>>856 俺はこんな感じにしてるけど。
class Foo
{
// プライベートなメンバ変数の定義
public:
// コンストラクタに始まるパブリックインターフェイス
protected:
// 派生クラスへのインターフェイス
private:
// プライベートなメンバ関数
};
860 :
855 :2006/02/11(土) 17:29:09
>>857 そんなのは知ってるよ。
でもこの仕様に決めた理由がわからないのに変わりは無いよ。
>>860 そんなのは知ってるよ。
でも お前が無知なのに変わりは無いよ。
C++で、クラスのprivateメンバ変数の数とかサイズとかが 真っ先に気にならない奴って、C++におけるコピーとか代入とか STLコレクションの挙動とかを全く理解してないんだろうと推測できる。 privateメンバ変数が超巨大で、その下に書いてあるpublic部分が 画面外に追いやられるような状況なら、分割かpimplを真剣に検討すべき。
今北産業だがD&Eも読まずに話している連中が多いのはわかった。
>863 あんたはSTLコンテナのイテレータが保持しているメンバ変数の数とかサイズとかを気にしているの?
現場でルールとして決められたらそれに従う、これが守れりゃいいんだろ?
sizeofが信用できないので自分で計算します。
ルールを決められる立場ならそれでいいが、 ルールを決める立場には問題が残る。
>>869 だからって真っ先には気にならない。
クラス定義に現れる順番は public インターフェースの後ろでいい。
内部の細かい仕様を覗き見させないで
知っとかないと問題のある事は仕様として公開するべきじゃないのか?
>>869 の例なら内部に巨大なデータを保持していてコピーに時間がかかる事を
書いておくな俺だったら
>>871 コンストラクタをprivateにしてSingletonや継承禁止にしたり、
コピーコンストラクタや代入演算子をprivateにしたりする事があるよな。
「明示的にprivateにしている」事もpublicインターフェイスを
構成している(コピーできない、構築できない、継承できない等)
場合があるが、お前はそれはどこに書くの?
>>872 >内部の細かい仕様を覗き見させないで
それは要するにpimplで解決。
>知っとかないと問題のある事は仕様として公開するべきじゃないのか
C++の場合、例えprivateでも、メンバ変数のサイズは
「知っとかないと問題のある事」の1つだろ。
private関数は、ユーザーが知る必要は全くないけど。
いや そのりくつは おかしい。
>>873 はクラスを見たとき必ずprivateを真っ先に見るのか?
privateの中身が問題になる事があるって言っても
publicよりprivateのほうを良く見るって事にはならないだろ
>>874 ヘッダにクラス設計として実装されてることを公開って言ってるわけじゃない。
876 :
871 :2006/02/11(土) 19:25:07
>>873 コピー不可については自明なことも多いので
boost::noncopyable が使えればそれで。
使えなければ単純な private ブロックの直前に別で書く。
// noncopyable
private:
例の奴ら
private:
...
その他、構築できない、継承できないなどは
クラスについてのコメントとしてクラス定義の直前に理由を添えて書く。
>>874 private なメンバ変数のサイズをクラス定義を見て知ったとしても、
それに依存したコードを書くのはダメだろ。
問題が起こってから解決のためにサイズに依存した
回避コードを書くことはあるかもしれないが。
ARMとかD&Eとかでは、classかstructかに関係なく、 メンバ変数は先頭にアクセス指定無しで書かれてる。 structならpublic、classならprivateとなる。 Bjarneとしては、classとstructの違いを活かして メンバ変数は先頭にまとめて書け、って方針みたいだ。
>>877 sizeof(class)に依存したコードなんて書く池沼がどこにいるの?
>>878 ふむ、ってことは、
先頭にメンバ変数を書かないのは基本的にはマイナーな俺ルールなのか。
自分の書き方は先頭派で禿と同じで少し安心。
>>879 さぁ? >874 あたりにいるんじゃないか?
確か禿はユーザーが気になるのはpublicインターフェースだから
先にpublicを書けと言っていたはずだが
>>878 >>880 すごい自演を見た
>>882 それはメンバ関数の話じゃないの?
禿げの本では、どれもメンバ変数は先頭に書いてるよ。
>>883 public->privateの順で書くよりも
private->publicの順で書く方がprivateが短く書けるから
本ではそう書くようにしているとも言っている
- privateが短く書けるから + privateをを省略出来て短く書けるから
888 :
デフォルトの名無しさん :2006/02/11(土) 21:04:56
>>816 遅レスだが・・
print()をインターフェースで分離する・・に1票
>privateをを省略出来て短く書けるから いやちょっとその意見にはさすがに納得できない
>>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 ])();
}
こんな方法もあるにはあるけど。
>>889 書籍にコードを載せる際には、そういうのが結構あるんじゃないかと思う。
public:
とかだけで普通、一行食うし。
892 :
デフォルトの名無しさん :2006/02/11(土) 21:30:40
>>890 >>816 をそのまま実現すると巨大な一枚岩クラスの温床になりかねないので
そこから「改造」したいなあぁ・・って感じです
使い捨てAPLならば、switch〜caseに1票
「本ではこう書いてるけど実際のコードはどっちがいいのか知らん」 って意味か
プロポーショナルフォントでソースコード印刷する人だからなぁ。
public:やprivate;を書くか書かないでよくここまで盛り上がることが出来るな。 一秒のtypingをケチるような奴は関数名や変数名もろくでも無いものにしているのだろうな。
delete this; ってありですか?
>>897 できる。
もちろんそれ以降メンバ変数・関数を扱わないこと。
また、大抵の場合はnewで確保されたものでないとだめだろうから、それにも気を付けること。
>>899 ありがとうございます。
できるんですね。
自己消滅できれば便利なのになーとか考えてたんですが、
delete thisについて書かれてるようなものが見つからなかったので,,,
>>901 ありがとうございます。
その二つは見つけてませんでした。すいません。
ただ、それほど面倒なことにはならないなぁってのが第一感想です
#もちろんきーつけて使えばの話ですが。
903 :
デフォルトの名無しさん :2006/02/11(土) 23:13:51
delete this、の有用性は時と場合によるかと
すれどのラッパークラスとかの場合は便利
>>901 > CWnd::GetSafeHwnd()
目から鱗が2枚落ちました
>>903-904 ヌルポインタに対するメンバ関数呼び出しの時点で未定義動作だ。
仮想関数関係無しに真似しちゃイカン。
>>905 やべ、そうだったのか。
ってことは
struct tree{
int value;
tree*left,*right;
int size(){
return this?left->size()+right->size()+1:0;
}
};
こういうソースは駄目なのか......
んー面倒だなー
>>906 そんなソース、貧乏人しか書かない時代なんだが。
908 :
906 :2006/02/12(日) 01:44:25
いや、まぁこれ位ならsetなりmultisetなりを使うけどさ、 これ以外にも自己再帰的なデータ構造を扱うときに this==NULLを終端条件とした再帰を書きたくならない? 俺は結構なるけどなー。まぁ未定義らしいしやめとくか
910 :
デフォルトの名無しさん :2006/02/12(日) 11:37:35
>>905 あらま・・ヌルオブジェクトパターンを簡易に書けるかと思ったら
VC限定仕様だったみたいですね
>>906 もそれは同じ・・かな
限定とは言わんが、鼻から悪魔だな。
operator<<と>>を間違えていたのに気づかず、こんな時間だ。 なぜこんなにもSTLのエラーメッセージはわかりづらいのだろう?
馬鹿を切り捨てるわかりづらさは問題だよなやっぱ。
915 :
デフォルトの名無しさん :2006/02/14(火) 08:40:35
そういうひとはVBを使ってください
いやー、ロジックの方にばかり目がいってしまった。 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++ だろ?
エラーメッセージ翻訳フィルタでも作ればウケるかも
>>917 std::vector じゃダメか?コピーコンストラクタ要るけど。
>>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 そういう形式の初期化はできますね。
配列の要素一つごとにざくっとコンストラクタ
呼んでくれればべんりだなぁ、と。
>>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);
のようにして全部同じコンストラクタ連続的に呼んでくれたらな、って。
struct OreGenerator { OreClass value; OreGenerator() : value( 10, 0 ){} // 適当な初期値 operator OreClass() const{ return value; } }; std::vector<OreGenerator> v( 100 ); OreClass ore = v[0];
>>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> って中身は
まんま配列っぽい。
OreはねーよOreは
929 :
デフォルトの名無しさん :2006/02/14(火) 11:35:00
それにしてもテンプレート使うと、エラーが出たときに テンプレートクラスを定義しているヘッダファイルの 行番号が表示されるから、いったいどこの実体化で エラーになったのか分かりづらいっすね。
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 なんかもうちっとマシなメッセージ吐くぞ
ときどき日本語おかしかったりするけど
>>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 と思ったけど何か違うみたい
スルー推奨
>>934 *((int*)vp)++
だとうまくいくみたい。
キャストと++は同順位で右左だから、という説明でいいのかな。
938 :
デフォルトの名無しさん :2006/02/14(火) 14:52:58
939 :
デフォルトの名無しさん :2006/02/14(火) 14:53:51
>>937 それVC++2003toolkitだとC2105だった。
941 :
937 :2006/02/14(火) 16:41:41
ほんとだ。g++でも怒られた。bccと俺が甘いってことか。 すまんかった>934
942 :
デフォルトの名無しさん :2006/02/14(火) 17:27:47
>キャストと++は同順位で右左だから、という説明でいいのかな。 よくない 規格票でも K&R でもいいが、 単項と後置の優先順位を確認してみては?
943 :
934 :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;
は試したか?
>>934 組み込み型のインクリメント演算子などのオペランドには左辺値が必要。
だからこうして参照を使えばとりあえずできる。
typedef int* pint;
*reinterpret_cast<pint&>(vp)++ = 10;
ちなみにtypedefを使わないでやるとするとreinterpret_cast<int&*>(vp)になる。
946 :
934 :2006/02/14(火) 18:10:29
>>944 無名共用体を使う場合、どうやるのかイメージが湧きませんでした。
なるほど、そういう意味だったのですね!
vpが引数で与えられてるので、共用体でやるとしたら、無名じゃない共用体で、という事でしょうか。
それでも、共用体の方が可読性いいかもしれませんね。
ありがとうございました。
947 :
934 :2006/02/14(火) 18:13:34
>>945 reinterpret_cast<int&*>(vp)
すみません・・・これ、なんという手法ですか?
勉強不足でお恥ずかしいのですが、よく知らないのです。
ググってきますので、ヒント下さいますでしょうか?
C++さんです
950 :
デフォルトの名無しさん :2006/02/14(火) 18:28:27
>>945 int&* って何だ? ( int*& なら知ってるが)
951 :
945 :2006/02/14(火) 19:03:00
>>944 ,945
実装依存なのはわかって言ってるんだろうな?
953 :
デフォルトの名無しさん :2006/02/14(火) 23:10:53
>>952 void* が必要な場面で実装非依存とは、例えば?
>>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);
}
>>953 pthread_create() とか。
956 :
デフォルトの名無しさん :2006/02/14(火) 23:26:45
>>954 意図が見えない
もともと int* だったのが明らかでキャストし直していると言うならそもそも void* にする必要性はないし
例えばと言ったのはコード片じゃなく応用分野だ
int* pi = 0;
void* pv = pi;
↑
こんなのをわざわざ尋ねたりはしない
バイトストリームを生成する関数とか
>>956 somefuncはライブラリ関数で、コールバックと、それに渡す補助データとしてvoid *の値を取る、と考えてくれ。
somefuncのユーザは、コールバックにint *を渡したいが、型を合わせるためにいったんvoid *にキャストして渡し、
それをコールバックで受けてint *に戻して使う。
959 :
958 :2006/02/14(火) 23:40:54
こんな例出さなくてもqsortで十分だった…
960 :
デフォルトの名無しさん :2006/02/14(火) 23:41:04
次スレはどーすんべ?
962 :
デフォルトの名無しさん :2006/02/14(火) 23:43:22
964 :
デフォルトの名無しさん :2006/02/14(火) 23:45:00
>>959 <algorithm> ではなく extern "C" 関数を使う場面とその理由は?
ほんとに初歩的な質問。 初歩的過ぎてなんて調べたら良いのか分からないのでここで。 a[1][1],a1][2],a[2][1]a[2][2] = 1; ってやるとエラー吐くんですけど、括弧とかどこに付けたら良いですかね(´・ω・`)
966 :
958 :2006/02/14(火) 23:45:11
967 :
デフォルトの名無しさん :2006/02/14(火) 23:45:18
>>962 944,945 は void* と int* の表現形式に互換性があることに依存している。
例えば void* が 64bit で int* が 32bit だったら不味いことになる。
969 :
958 :2006/02/14(火) 23:46:45
>>964 説明のためだから。
>>965 何がしたい?四箇所に一を代入したいなら、
a[1][1] = a[1][2] = a[2][1] = a[2][2] = 1;
970 :
965 :2006/02/14(火) 23:47:56
>>969 どうもです。今までわざわざ四回書いてたので同時に代入する方法知りたいと思ったわけです
ありがとうございました
971 :
デフォルトの名無しさん :2006/02/14(火) 23:56:24
972 :
デフォルトの名無しさん :2006/02/14(火) 23:57:15
973 :
デフォルトの名無しさん :2006/02/15(水) 00:00:40
>>971 「何が」の違いは今あなたが持ち出したことだ
974 :
958 :2006/02/15(水) 00:03:31
>>972 >そんなら qsort も実装依存ですな
int *とvoid *の表現形式が違ったとしても、
int *からvoid *に変換し、それをさらにint *に戻したとき、
これが最初の値と変わらないことは規格で保障されている。
だから、qsortは実装依存ではない。
>じゃ、
>>956 へのレスとして何の説明がしたかったんだ??
実装に依存せずにvoid *を使うことができる、ということ。
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
お前らの話はよーーーく分かった だから、次スレよろ
自分が間違ってるかもしれないという可能性を認められないガキが紛れ込んだな。 さっさと次スレに移るか。
>>968 任意のデータ型のポインタをvoid*に代入し
再度元のデータ型に戻すと、元のポインタが確実に復元できることは規格で保証されている。
・・・Cでは。
C++でも、Cスタイル/static/reinterpretなキャストなら
(つーか、void*にdynamic_castとか出来ないし)
保証されていそうな気がするが。
今テンプレ整理してるからもうちょっと待ってて。
980 :
デフォルトの名無しさん :2006/02/15(水) 00:17:34
981 :
デフォルトの名無しさん :2006/02/15(水) 00:18:35
正直正規表現わかりにクス while($s =~ /^(.).*/g) とか $a =~ s/^(.)//; とか 意味わからなす・・ perl これをC++でよろしく。
>>981 状態遷移表くらい書けるようになっとけよ
984 :
デフォルトの名無しさん :2006/02/15(水) 00:22:20
>>978 >>968 はそんなこと分かってると思うんだが。
>>968 が問題にしてるのは、正規の変換を経ずに
unionや参照のキャストを使ってvoid *をint *として扱った場合の話だろ。
>>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 あなたが何を主張しているのかはわかった
reinterpret_castって一番好き勝手出来る奴だろ? あれってC形式のキャストと変わらなくね
993 :
デフォルトの名無しさん :2006/02/15(水) 00:29:28
>>991 static_cast ではなく reinterpret_cast を使う場合の理由と
無名の共用体を使う場合の理由はどう違うんだ?
もうねstl作れ さもなきゃdefineしろ それもだめなら考えうる全ての型を実装しろ ってこと? 次スレまだー?
995 :
デフォルトの名無しさん :2006/02/15(水) 00:33:27
>>986 参考のサイトを参照しながら
$a =~ s/^(.)//;
はわかった。
Cでの書き方もおそらくわかると思うけど
$s =~ /^(.).*/g
もっと詳しく教えてくれ。
~ /^(.).これで一文字目と二文字目なのかな??
よくわからんからこれをCでどう書くのか
暇だったら世路。
>>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; 上と同じ */
997 :
996 :2006/02/15(水) 00:35:38
ごめん。 >pi = reinterpret_cast<int *>(pv); /* ok; 上と同じ */ これは無しで。
>>995 解釈は間違ってはないけど微妙に違う
^(.)これが1文字目なのはいいけど、次のは
.じゃなく.*で二文字目以降(無くても可能)って意味
それと正規表現Cで書くってどういうことだ?
まさか自動羊肉実装するのか?
面倒だから鬼車使っとけ
999 :
デフォルトの名無しさん :2006/02/15(水) 00:39:34
>>998 ふむなるほど。
いやなんかperlの奴を移植しようかと考えてるんだが
あわよくば
書いてくれるかなって思ったわけ。そこだけ
次スレナインか?
1000 :
デフォルトの名無しさん :2006/02/15(水) 00:40:45
ここでVIPPERが華麗に1000げと
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。