■過去ログ置き場に戻る■ 1- 前250 次250 最新50


[memo] "9999999999_00.html#R20" という感じで、URLの最後に "#RレスNo" を追加すると幸せになれます。

C++相談室 part26
501 名前:デフォルトの名無しさん :03/12/31 15:47
class と struct は C++ では基本的に同じものだけど、
やっぱり違う名前を使っている以上
使い分けはした方がいいと思うんだよね。
non-POD struct はなるべく作らないようにしてる。
まぁ、別の話ではあるが。

C++ ならメンバを 0 クリアするメンバ関数を作っておけば、
C ならメンバを 0 クリアするマクロか関数かを作っておけば、
memset にするかどうかを途中で変更できるんで、色々と楽ですな。

502 名前:デフォルトの名無しさん :03/12/31 15:53
俺メモ

POD (Plain Old Data)
古き良き単純なデータ、というか何と言おうか。

詳細な定義は、ISO C++ 規格の 9.4 にてなされていますが、 ぶっちゃけ、ユーザー定義の代入演算子や
デストラクタやらを持たない、 memcpyなどでメモリを直にいじってコピーしたりして問題のない オブジェクトのこと。

503 名前:デフォルトの名無しさん :03/12/31 16:26
>>501
標準ライブラリの作法ですでに
関数オブジェクトや traits なんかに struct が使われているのだから、
今更エンドユーザーが C-like な struct にのみ限定する意味が果たしてあるのか疑問だけどな。

オペレーターオーバーロードといっしょで宗教論争になってしまうが。

504 名前:デフォルトの名無しさん :03/12/31 16:28
宗教論争は避けたいので
class と struct の使い分けに関してはここで 糸冬 了

505 名前:デフォルトの名無しさん :03/12/31 16:48
ZeroMemoryはAPIに渡す構造体の初期化ぐらいにしか
使わない。

506 名前:デフォルトの名無しさん :03/12/31 17:23
ZeroMemory って、memset をラップしてるだけのマクロなんだよね。

507 名前:デフォルトの名無しさん :03/12/31 18:07
うん。そんでWTLの話だけど7.0から7.1に変わったら、
構造体の初期化がmemsetから{0}に変わってた。

508 名前:デフォルトの名無しさん :03/12/31 20:04
>>502
あるデータ構造に対して、
それを直接処理する専用のハードウェアが用意されているとき、
そのデータ構造をPODという

・・・なんてのはどうだい?

509 名前:デフォルトの名無しさん :03/12/31 21:06
どうだいもなにもここは(標準の)C++のスレであって勝手に俺定義を持ち出されてもな……。
仮にそういう名称を与えて何の役に立つ?
既存の概念の拡張にすらなっていないと思うんだが。

510 名前:デフォルトの名無しさん :03/12/31 21:08
意味がよくわからんが、fpuがエミュだとfloat, doubleが
PODで無くなるのか?

511 名前:デフォルトの名無しさん :04/01/01 02:24
PODと非PODに分類することの、そもそもの意図は?

512 名前:デフォルトの名無しさん :04/01/01 02:38
>>497 >>499
あけましておめでとうございます。

479です。

31.412.2 2.132.1
23.1

フォーマットですが、499氏の言う通りで、
4桁ずつ取り出して処理する固定長データファイルで、
データ間に区切りは存在しません。
適当な桁数ごと(この場合は16桁ごと)に改行が入っています。
つまり、データとしては、「31.4」「12.2」「2.1」「32.1」「23.1」の5個です。
小数点は「.」で、小数表記は通常のものです(科学表記ではなくて)。
(この場合32.1の後で改行)

何をしたいか、というと、FORTRANのWRITE文で
作成したデータファイルをC++で読みたいのですが、何かいい方法はないかな、と思って。


513 名前:デフォルトの名無しさん :04/01/01 02:47
続き。

FORTRANだと、この手のファイルは、

READ( 61,650 ) ( A( I ), I=1,X )
650 FORMAT( 4F4.1 )

のような形ですぐに読めてしまうんだけど、C++だと、
scanfを使う場合、4個分すべてフォーマットを記述しないとならないし、
最終行は4個データがあるとは限らないので、特別な処理を必要とします。

何かうまい書き方がないかな、と思って質問しました。

できれば、FORTRANで作成したデータファイルを読むことが多いので、
拡張してライブラリを作っておきたい、というのもあります。
# f2cだと、入出力と型がf2cに特化されていて、一般的なC++の
# プログラムで使いにくいので。

514 名前:デフォルトの名無しさん :04/01/01 03:20
fortranで作ったプロシージャをCから呼び出すためのラッパーをアセンブラで作ったら?

515 名前:デフォルトの名無しさん :04/01/01 07:28
fortran で作ったプロシージャは
C++ から単純に呼び出せる。

   procedure test(a, b)
    integer a, b
    a = b
    return
   end

#define FNAME(name) name##_ // このあたりはコンパイラによって変わるので #if で分岐してちょ
extern "C" void FNAME(test)(int& a, int& b);

int main() {
 int a, b = 3;
 test(a, b);
}

あとはライブラリをどうにかすれば OK 。
これも指定の仕方はコンパイラによって変わる。

516 名前:デフォルトの名無しさん :04/01/01 08:04
>>513
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;

int main() {
 static const int PerLine = 4;
 static const char formatIn [] = "%4lf";
 static const char formatOut[] = "%8.2f";
 static const char Filename [] = "test.txt";

 FILE* file = fopen(Filename, "r");
 if(file == NULL) { return EXIT_FAILURE; }

 int total;
 do {
  double a[PerLine];

  for(total = 0; total < PerLine; ++total) {
   if(fscanf(file, formatIn, &a[total]) == EOF) { break; }
  }
  for(int i = 0; i < total; ++i) {
   printf(formatOut, a[i]);
  }
  puts("");
 } while(total == PerLine);
 fclose(file);
}

517 名前:デフォルトの名無しさん :04/01/01 09:18
C 非互換のオブジェクトを extern "C" で呼び出した結果は未定義
extern "FORTRAN" が使えるかどうかは処理系定義

規格の観点からは後者の方が正しい

518 名前:デフォルトの名無しさん :04/01/01 09:33
でも、実際問題 FORTRAN と C の相互運用が
できるようにしてあるのが普通。

519 名前:デフォルトの名無しさん :04/01/01 10:38
それ以前にCで読みやすい形にして出すのが普通

char line[MAXLINE];
char *p = line;

while (fgets(line, MAXLINE, fp) != NULL)
{
 p = line;
 while (*p && *p != '\n')
 {
  char num[4 + 1];
  if (!(num[0] = *p++)) break;
  if (!(num[1] = *p++)) break;
  if (!(num[2] = *p++)) break;
  if (!(num[3] = *p++)) break;
  if (!(num[4] = '\0')) break;
  double d = strtod(num, 0);
  printf("%f\n", d);
 }
}


520 名前:デフォルトの名無しさん :04/01/01 11:14
それ以前に喪前のコードは汚い。

521 名前:デフォルトの名無しさん :04/01/01 12:45
改行が(目に見えない)文字コードを持っていて
区切り文字として扱われることはわかってるんだろうか。


522 名前:デフォルトの名無しさん :04/01/01 12:48
何か変なフォーマットだな…。
漏れだったら数字と数字の間には必ず
スペース1個入れると思うぞ。
もしくは、freadで一発で読めるようにするか。

523 名前:デフォルトの名無しさん :04/01/01 12:52
つーか固定長指定フォーマットであることを利用した変換関数を作らない限り
固定長専用の読み込みコードを書く意味はほとんどないんじゃないか?
不正な入力を途中で検出しやすいかというとこの場合はそうはなりそうにないし。


524 名前:デフォルトの名無しさん :04/01/01 14:30
>>519
必ずしもそうはいかないことあるよ実際。
メインフレームのライブラリをナメたらあかん。

525 名前:デフォルトの名無しさん :04/01/01 15:48
FORTRAN だと固定長のやつが簡単に扱えるので
空白を入れないことも多い。

526 名前:デフォルトの名無しさん :04/01/01 15:57
先人の遺したライブラリだと固定長でスペース一個空いてるのでスペースを区切りに使おうとすると、
値が無限大(log(0)計算)のときに指定された幅を*******……で全部埋め尽くされてしまい、あぼーん。

……fortranは嫌いだ

527 名前:デフォルトの名無しさん :04/01/01 17:47
固定長データの読み込みならfscanf使えばいいじゃん。
fstreamにこだわる?


528 名前:デフォルトの名無しさん :04/01/01 18:00
固定長ならistream::read?

529 名前:デフォルトの名無しさん :04/01/01 18:19
istream のメンバ関数を使う場合(グローバルでもあるけど)、
文字列を得る上で終端文字がほしいなら
get, getline系
いらなければ読み取り文字数と戻り値に応じて
read か readsome だな。

fscanf 使えば? ってのは最初のレスにもあるが。
ただ速いけどその分安全性とか拡張性や
エラー処理が不十分だし、一応 C++ のスレってことで


530 名前:デフォルトの名無しさん :04/01/01 18:23
>>529
fscanfの安全性、エラー処理のどこに不満があるの?
必要な機能はそろっているのに。

拡張性がないのは同意しましょう。


531 名前:デフォルトの名無しさん :04/01/01 18:30
>>529

>ただ速いけどその分安全性とか拡張性や
>エラー処理が不十分だし、

危険なコードしか書けないのもエラー処理が十分にできないのも
みんなあなたの技量によるところで、fscanfは無罪。

拡張性については、fscanfそのものを拡張というパラダイムがそもそも間違い。
fscanfを内部で呼び出している拡張版の関数を作るべき。


>一応 C++ のスレってことで

#include <cstdio> // 気は確かか?

532 名前:デフォルトの名無しさん :04/01/01 18:58
また宗教論争が始まりそう。
頭に血が上っているヤツのために断っておくと、別に scanf 系が駄目とか言ってるわけじゃないぞ。
むしろFORTRANとの連携とかローレベルな入力処理にはCの機能の方が適切だとも思ってる。
>>529の発言はそれまでの話の流れで C++ の機能でやるとしたら、
という意味合いを含んでいるんだがわかりにくかったか?


533 名前:デフォルトの名無しさん :04/01/01 20:19
>>532
まぁ、宗教かも知れんな。

俺はバイナリ直で読み書きする場合には fread(), fwrite() で、それ以上のデータ構造を
持たせる場合は boost の正規表現ライブラリ、もしくは lex + yacc にしちゃってる。

動けば何でもよし。

534 名前:デフォルトの名無しさん :04/01/01 20:49
宗教論争とは違うでしょ。
scanf/fscanfが危険だなんていうやつは、ただの無知。
getsが危険なのとは全く違う。


535 名前:話ずれすぎな上に愚痴っぽくてすまんが :04/01/01 21:41
どっちかっつうと可変個引数リストの問題だが
型安全性の欠如はやっぱり問題ないと言い切るのは無理があるんじゃないかと思う。

使用時のミスはプログラマーの責任っちゃそれまでだが、
書式文字列がリテラルじゃないときなんかは特に
「外から」異常状態をチェックして適切な処理を記述するのは困難になる。

たとえば引数中何番目でエラーがおきたかはわかっても、
その型が何であるかという情報すら通常の方法では提供されないわけで。
この辺不完全性を感じなくもない。


536 名前:デフォルトの名無しさん :04/01/01 21:57
そもそも低レベルな入出力ライブラリだし
想定される入力元はほとんどブラックボックスだしで
復帰処理やストリームの状態チェックに関して多くを期待するのは無理な話だとわかっているのだが

文字列としてバッファリングした後に sscanf を使ってファイルの内容を読み込む場合、
ストリームの読み込み位置の情報を受け取っておけば、
復帰処理やエラー出力をするのは比較的やりやすい。
だけど scanf / fscanf の場合、ストリームの読み込み位置を戻せても
それが元と同じ内容を指しているとは限らなかったはず(保証あったらスマン)。

そういう点で、 scanf / fscanf をそのまま使うのは厳しくないのだろうか?
一応質問ってことで「そんなことないぞ阿呆」って言える人は是非後者の場合の対応方法を教えて欲しい。

537 名前:デフォルトの名無しさん :04/01/01 22:13
>>536
入力がテキストの場合だと、ふつー行単位でバッファに読み込んで、その中を
ポインタで動きつつ処理じゃないかね。

iostream が中途半端なのは、しょせん「型」が明確にわかってる場合にしか
使えないし、メンバ中にポインタがからむとアウトという点。いわゆるシリアライズ
処理を実装しようと思ったら、けっきょく ifstream なんか捨て捨てで、自分で
そのあたりの処理を 1 から作る必要がある。

538 名前:デフォルトの名無しさん :04/01/01 22:30
>>537
素朴なつっこみなんだが
型判定部分さえ作ってしまえばそこから先は
IO ストリームライブラリに処理を任せてもしまえばよいのではないか。

高レベルなシリアライズの場合は
むろん型情報を付加してやる際に元のフォーマットに追加しにくいこともあるだろうし、
ネストされたクラスを組み立てていくには境界付けを行うための
特別なフォーマットなんかを用意してやらないと実用に耐えないことになると思うが


539 名前:デフォルトの名無しさん :04/01/02 01:17
>>535
「外から」って?
書式制御文字列をユーザに入力させるってことなら
そういう設計をしたアフォにケリ入れるのが正道だろう。

タコなミスを書いてもコンパイルエラーにならない点は俺も不便を感じているが
そんなのはエラーの中では普通であって幸運ではないだけだ。


>>536
低レベルって?
標準ではPODのみサポートし、それ以外はユーザ定義の関数で対応なら、std::cinも同じこと。
表面的に関数名を同じに見せかけられるか否かの違いでしかない。
テンプレートやマクロを作るときに都合がよかったりはするが、レベルとか言う問題とは違う。

fscanf ・・・ストリーム中のエラー発生箇所がバイト単位でわかる
sscanf ・・・バッファ内のエラー発生箇所はわからない(ポインタを返せない)+バッファサイズが保守しづらい

俺はscanf系の中でsscanfだけはgetsと同格に見ている。

540 名前:デフォルトの名無しさん :04/01/02 02:26
>>536
まあ結局一文字ずつ読んで自前で処理した方が
必要な処理もしやすいし、よけいなことを気にせずに済むかな。

>>539
レスきちんと読んでないのか俺の書き方が不足しているのか、対話が成立していない気がする。

>低レベルって?
続いて復帰処理や状態チェックのための関数が用意されているのかって話出してるじゃない……。

>fscanf
エラー発生箇所を突き止めてその後、
その直前の位置まで復帰させて再読み取りする方法があるかなどについて聞きたいわけ。

ていうか
>バッファ内のエラー発生箇所はわからない
は嘘でしょ。
確かに入力元として渡したポインタが直接動いてくれることはないが、
(その必要もないしときにそれは困ったことを引き起こす)
読み込んだ文字数を得ることは可能。
そもそもそれがわかる前提で>>536のレスを書いてるのは明らかだと思うんだけど。

ただ C-FAQ Chapter-12 と逆の主張が出てる点は興味深いんで、もう少し詳しく説明して欲しい。

541 名前:デフォルトの名無しさん :04/01/02 03:05
>>540
まあ正直言えば、斜め読みっぽいところはある。あくまで2chだからね。
とは言うものの、あなたにここまで言われるほどでもないと思っているぞ。
>レスきちんと読んでないのか俺の書き方が不足しているのか、対話が成立していない気がする。

>続いて復帰処理や状態チェックのための関数が用意されているのかって話出してるじゃない……。
出しかけてはいるようだが、どこがscanf系の論評なのかわからない。
制御情報の一部を隠蔽するのはむしろ高レベルと違うのか?
それとも低レベルとは出来が悪いという意味なら肝心なことを書いていないのと違うか?

>その直前の位置まで復帰させて再読み取りする方法があるかなどについて聞きたいわけ。
最後にungetcして出てきてるやん。

>読み込んだ文字数を得ることは可能。
どうやって?

542 名前:デフォルトの名無しさん :04/01/02 03:23
そもそもパケット破損は検出位置と破損位置がふつう一致しない。
訂正処理はプロトコルの一部として設計すべき。

543 名前:デフォルトの名無しさん :04/01/02 03:31
そこでなぜ通信プロトコル(?)の話が出てくるのかなぞだが。

テキストファイルを扱う場合には、普通は「字句解析」「構文解析」を分離するわけだが
scanf(), istream 系を使うと、簡単なフォーマットなら両方まとめて書ける。ただ、少し
複雑になったり、エラー回復処理を入れようと思うと、両方まとめたことが逆に仇になる。
それだけの話じゃないのか?

俺は、やっつけ仕事を除いては、自前でトークン列まで切り出してから sscanf() で
型変換してる。

544 名前:デフォルトの名無しさん :04/01/02 03:34
質問で〜すぅ。うぐぅ。
template<class X>
class C
{
public :
  void operator ()(const X&){}
};

template<>
void C<int*>::operator () (int*const&){cout<<"C<int*>"<<endl;}
これってオーバーロードと解釈?。それとも、テンプレートの特殊化?。
それともうひとつ。
char (6f())[2];のような配列を参照にしてその型をなまであつかえることに気づいた
ひとって日本人?それとも外国人?
だれかおしえてくださいな♥

545 名前:デフォルトの名無しさん :04/01/02 03:36
>char (6f())[2];
char (&())[2];まちがえた

546 名前:デフォルトの名無しさん :04/01/02 03:38
複雑なら俺はパーサ作る。
出来合いのパーサ(scanf)で間に合わないときの当たり前の対応だ。

# 542は確かに蛇足

547 名前:デフォルトの名無しさん :04/01/02 03:42
>>544
なぜオーバーロードかも知れないと思ったんだ?

>日本人?それとも外国人?
こいつとhttp://www.cs.bell-labs.com/who/dmr/
こいつ。http://www.research.att.com/~bs/

548 名前:544 :04/01/02 03:52
>>547
すばやいご回答に感謝。
え〜とですね。
テンプレート特殊化でクラスの再宣言していからそう思った次第です。
それに部分特殊化も出来ないし。

禿さんだったのか。なかなかやるな。


549 名前:デフォルトの名無しさん :04/01/02 03:54
>>543
やっつけじゃない仕事にえらいもん使うんだな(((( ;゚Д゚)))ガクガクブルブル

550 名前:デフォルトの名無しさん :04/01/02 04:03
>>548
もしかして特殊化の使い方がうまくないのか?
template<class X>
class C : public C_base<X>
{
public :
};
としておいて二度手間にしたくない部分をC_baseに詰め込むなんて手もあるが。

551 名前:544 :04/01/02 04:28
>>550
えーとですね。
せっかく答えていただいてなんですが。
テンブレートに関してはMC++Dとか読んでかなり勉強したんですよね。
でもつい先日>>544のようなコードを見掛けたのですよ。
そして、えっ。これって、コンパイルされるの?
だって、特殊化のためのクラス宣言がないよ。て、感じて、コンパイルしてみたらあっさり通るじゃないですか。
「ありゃ」、「ありゃりゃ」。どうなってるの?てな訳で今に云ったってるわけなんですよ。




552 名前:デフォルトの名無しさん :04/01/02 04:41
>>551
だったら聞く相手まちがって内科医?

これ持ってる?

http://www.webstore.jsa.or.jp/webstore/Com/FlowControl.jsp?lang=jp&bunsyoId=ISO%2FIEC+14882%3A2003&dantaiCd=ISO&status=1&pageNo=0

553 名前:デフォルトの名無しさん :04/01/02 04:43
テンブレートは習ったことないんでよくわかんないや。

554 名前:544 :04/01/02 05:22
>>552
ごめんなさい。英語読めないんです。
やっぱ、洋書ぐらい読めないときついか。

555 名前:  :04/01/02 05:44
Kさん 好循環  Aさん 悪循環  
 (健康体)  (喘息)

1.(神が喘息であるかないかを決める)
2.K 喘息でない人 A 喘息の人は
は体力がある    体力がなくなる

3.K        A 行動力、
          五感(嗅覚)が鈍り感性が変化する

4.K&A 神は異常な感性の人間は本来人に迷惑をかけ
るから外に出てはいけないと思っている。

5.K 変化なし   A アトピーになる
6.K 正常な感性  A 外に出なくなりさらに異常な感性になる
7.K 正常な人間   A 異常な人間(レッテル)
8.K&A 死  9.K&A      来世
10.K&A 神は異常な人間は人に迷惑をかけるので行動
を抑制する必要があると思っている。

11.K&A 神が喘息であるかないかを決める
12.K 喘息でない  A 喘息である
13.K&A    1.に戻る

これは事実。広めようぜ
解決法:寝て起きて、やな気分でも、続けるけること。
体力をつけると感覚が正常に戻り、
アトピーも快癒に向かう。 目安としてグランドを10週くらい。
あとはウォーキング 2.3時間を目安にウインドーショッピングや本屋めぐり

556 名前:デフォルトの名無しさん :04/01/02 06:40
最近、変質者が小学生を襲ったりする事件が頻発してるのはお前が
そんな電波だしてるせいで変質者が外出するようになったからか。

>>555 は氏ぬべきである。しかもただ氏んで終わるものでは(以下略

557 名前:デフォルトの名無しさん :04/01/02 11:52
>>554
552が貼ったリンクをよく嫁
JIS規格、つまり日本語版があるって書いてあるやん

558 名前:デフォルトの名無しさん :04/01/02 12:00
>>557
JISのは英語だよ、邦訳は出てない。

559 名前:540 :04/01/02 12:43
今更長レスするのも何だけど
>>541
低レベルという呼称に良否を下されたと思って腹を立てている? なら誤解だ。
抽象度の高くモデル化されたファイル入力をかなり直接的に扱う stdio と
例外機構や多数の関数群などの提供する機能の豊富さ/肥大さを持った iostream の性質の違いを指してる。
iostream ファミリのエラー処理機構が scanf 系に比べ
それほど満足できるもんじゃないと言うのなら、確かにそうだ。

で、ungetc が fscanf に対しても使えるとは知らなかった。
(むしろ内部バッファの処理と衝突しそうな気もするんだけど……)
が、それが出来ても「読み出したものを戻す」戦略が「貯えたバッファ内をランダムアクセスする」戦略に対して
殊エラーからの復帰処理に関して同程度に置けるものとはやはり到底思えない。

読み込んだ文字数を得るには "%n" を指定する。
つかこれできないとエラー復帰処理以前に
一つのストリームから段階分けて読み込むことすらできないあり得ない関数になってしまう。


560 名前:デフォルトの名無しさん :04/01/02 12:44
>>558
まぢっすか?
買わなくてよかった

561 名前:デフォルトの名無しさん :04/01/02 22:29
『標準入力からテキストファイルを読み込み、単語を検出して辞書順に並べ、出現頻度を標準出力に出力しなさい。』
って宿題があるのですが分かる方お願いします。オートマトンとかそういうのを使っていたと思うのですが・・・ 

562 名前:デフォルトの名無しさん :04/01/02 22:38
単語の定義と辞書順の定義をまずはっきりと規定しなさい

563 名前:デフォルトの名無しさん :04/01/02 23:15
>>561
宿題スレへどうぞ。

ぼるじょあがC/C++の宿題を片づけますYO! 18代目
http://pc2.2ch.net/test/read.cgi/tech/1071407728/

564 名前:デフォルトの名無しさん :04/01/03 00:33
海外掲示板用オフラインリーダーを作るスレ
http://pc2.2ch.net/test/read.cgi/tech/1072883528/

海外でよく使われていうる掲示板スクリプト
専用のオフラインリーダー作って下さい。

必要な条件はID、PASSを管理できること、
OpenJaneみたいな三面型の見た目。
簡単にローカライズできるように言語ファイルを採用

565 名前:デフォルトの名無しさん :04/01/03 07:04
%5d、%-8d、%7.2f など Cでの数値の書式制御を
C++記述で表現する方法ってあるんでしょうか?

例)
int a=123;
printf("%5d", a);
実行結果 __123



int a=123;
cout << ?????


566 名前:デフォルトの名無しさん :04/01/03 07:13
setw
ios

567 名前:デフォルトの名無しさん :04/01/03 07:17
>>565
一通りある。まあ >>566 で十分わかるべきだが例:
cout << setw(5) << a;

568 名前:565 :04/01/03 07:30
>>566-567
ありがとうございました。。<(_ _)>

569 名前:デフォルトの名無しさん :04/01/03 13:48
boost::formatという手もある

570 名前:デフォルトの名無しさん :04/01/03 14:21
>>569
>565にはまだ早いような。
だって、operator << のオーバーロードが働いてる事も知らないよ。


571 名前:デフォルトの名無しさん :04/01/03 15:08
早いとかそういう問題じゃないだろ。
元の質問は明らかに標準のIOストリームライブラリについてのものなんだから。
使えるヤツには format の方がずっと使いやすいが初心者にまで見境なく勧める方が間違い。

572 名前:デフォルトの名無しさん :04/01/03 19:04
>>559
そんなもん使ったところでバッファサイズを決めうちしてる時点で(ry
・・・と言いたいところだが、%nには思い至っていなかった。
なので、ここで恥の上塗り的な即レスは悪いが中止するんであしからず。
また機会あったら議論しようぜ。

573 名前:デフォルトの名無しさん :04/01/04 05:32
C/C++相談室で放置されたので、こちらで質問させて下さい。
複数の引数を持つコンストラクタを使ったオブジェクト配列は作れるのでしょうか?
例えば私の知識では
myclass ob[3] = {myclass(1,1), myclass(1,1), myclass(1,1)};
とする方法しか存じておりませんが、この方法は
1) 各obに同じ引数を渡したいのに、各々引数を明示するのがバカっぽい
2) こんなことができるのはせいぜい数個の配列まで
の2点から、とても実用できるシロモノではありません。
そこで、こういったケースでは何を行うか、先輩方の御知恵を仰ぎたいのです。
よろしくお願い致します

// gcc 3.3.2 では ob[3] = myclass(1,1);でできちゃったけど、これは拡張機能?

574 名前:デフォルトの名無しさん :04/01/04 05:46
>>573
std::vector< myclass > ob( 3 , myclass( 1 , 1 ) );

575 名前:デフォルトの名無しさん :04/01/04 05:58
>>573
配列の要素となるオブジェクトは可能ならデフォルトコンストラクタ(と代入演算子)を用意する。
初期化子が途中で省略できないし、new[]もできないなどといろいろ困るので。

生成後に代入する手間はこの場合は気にしてはいけない。
どうしてもデフォルトコンストラクタが呼べない場合は、ポインタの配列を作って
1個1個 new するなり、他で作ったオブジェクトへのポインタを渡してやるなどするのが常道。
(たとえばすべての要素が同じ値を持っていて変更されないなら後者もアリ)

>>574
それデフォルトコンストラクタ呼んだ後でコピーしてるぞ。
(つーかSTLコンテナの要素はDefaultConstructableかつAssignableという要請がある)

576 名前:574 :04/01/04 06:09
>>575
どこでデフォルトコンストラクタが呼ばれるの?

577 名前:デフォルトの名無しさん :04/01/04 06:20
>>576
myclass の new[] を行うときに。

578 名前:574 :04/01/04 06:34
>>577
してねーよ。
コピーコンストラクタしか使ってない。

579 名前:デフォルトの名無しさん :04/01/04 06:48
STLの中にデフォルトコンストラクタを要求する操作があるが、
std::vectorのコンストラクタはそうでなかったような気が。

std::vectorのコンストラクタは無属性のメモリを予約サイズ分確保して、
必要な個数分、placemant new を使って初期化を行う。
初期化パラメータつきのstd::vectorのコンストラクタは
引数つきのplacement newを使用するんで、この場合デフォルトコンストラクタは
呼び出されないはず。

デフォルトコンストラクタが要求されるのは、例えば std::mapの operator [] とか
じゃないかな。


580 名前:デフォルトの名無しさん :04/01/04 06:52
>>575
> STLコンテナの要素はDefaultConstructableかつAssignableという要請がある
これは間違いだな。

23.1 -3-
The type of objects stored in these components must meet the requirements of CopyConstructible types, and the additional requirements of Assignable types.

581 名前:575 :04/01/04 07:01
ああそうか。
コピーは確かに必要だが、
メモリ確保しておくだけでいいからデフォルトコンストラクタが呼ばれる必要はないか。
すまん早とちりだ。>>574

582 名前:デフォルトの名無しさん :04/01/04 07:04
STLのコンテナはって言い方は確かに一般化のしすぎだったが
resize とかがあるから vector にはデフォルトコンストラクタは必要では?
#クラステンプレートだから使わない限り怒られないと思うけど。


583 名前:デフォルトの名無しさん :04/01/04 07:07
>>582
ob.resize( x , myclass( 1 , 1 ) );
もうちょっとちゃんと調べてからものを言ったほうがいいと思います。

584 名前:デフォルトの名無しさん :04/01/04 07:16
>>583
resize(size_type n , T t = T() ) だろ。

Sequence と Associative Container はやっぱり DefaultConstructible だ。
( list が Reversible Container で違うんだな)


585 名前:デフォルトの名無しさん :04/01/04 07:32
>>584
「使わない限り怒られない」から「デフォルトコンストラクタは必要」ではないです。

> Sequence と Associative Container はやっぱり DefaultConstructible だ。
> ( list が Reversible Container で違うんだな)

Sequence と Associative Container はたしかに DefaultConstructible ですが、
要素の型は DefaultConstructible である必要は無いはずです。
あやしいので情報元を示してください。

586 名前:デフォルトの名無しさん :04/01/04 07:40
要素の型と勘違いしてた。OTL
type に対して要求されてないと駄目なのね。
指摘ありがとう。


587 名前:デフォルトの名無しさん :04/01/05 11:58
年賀状は、謹賀、賀正などの「賀詞」、
新年おめでとうございます、などの「祝詞」で始まります。
「賀詞」の場合、“賀正”、“迎春”、“賀春”は、
目上の人に対して失礼な言葉なるので注意しましょう。
目上の人に対しては「祝詞」を使った方が無難です。

588 名前:デフォルトの名無しさん :04/01/05 12:28
>>587 へぇ〜 へぇ〜 へぇ〜 へぇ〜 へぇ〜

589 名前:デフォルトの名無しさん :04/01/05 13:29
でも多分目上の人もそう書かれて失礼だとは思わないよね。

590 名前:デフォルトの名無しさん :04/01/05 13:39
出力を.txt形式のものにしたいのですが,どうしたらよいでしょうか.

591 名前:デフォルトの名無しさん :04/01/05 13:42
リダイレクト

592 名前:デフォルトの名無しさん :04/01/05 13:48
fprintf

593 名前:デフォルトの名無しさん :04/01/05 20:47
Borland C++builder いがいに使いやすくて便利なものあれば教えてください

594 名前:デフォルトの名無しさん :04/01/05 21:36
Visual C++
Javaが動く環境ならEclipse+適当な言語

595 名前:デフォルトの名無しさん :04/01/06 00:26
ダイアログベースで簡単なプログラムを作りたいのですが
その中のいくつかの関数は int ,CString 型の変換ややり取りしかしません
それをコンソールでテストしながら作りたいのですが

CStringを使うときに必要なヘッダーを教えてください。

自分の力では検索で見つけられなかったのでお願いします

596 名前:デフォルトの名無しさん :04/01/06 00:28

コンソールで→Win32 Console Applicationで

597 名前:デフォルトの名無しさん :04/01/06 00:45
>>595
スレ違い。VC++スレにでも行って聞け。

598 名前:デフォルトの名無しさん :04/01/06 01:34
わかりました
どうも

599 名前:デフォルトの名無しさん :04/01/06 06:12
>>589

そもそもよまな(ry

600 名前:512 :04/01/06 07:38
>>512-513 の件、
皆さん、有り難うございました。

結局、 fscanf() で記述しました。
吐き出しは、boost::format() で。
>>516氏や>>519氏に似たコードです。

以前作成したときは、低レベル関数を使わないで、
と思ったので、getline()で読み込んだ後(>>529氏のレス参照)、
substr()で切り出したり、
特殊な場合('.'の位置によって区切り位置が変わってしまうときがある)は、
boost::tokenizerなどを駆使して、やっていたのですが、
FORTRANの場合、大人しくCの機能を使った方がよいようですね。

ちなみに、FORTRANはg77@Cygwinを、
C++はVC++7.1を使っているため、
>>515氏の方法は取っていません。

601 名前:512 :04/01/06 07:41
にしても、FORTRANをC++に移行する需要って
結構あると思うんですが、
そういったライブラリって、意外にないものなんですね。
(f2cだと入出力の部分は独自になってしまうし)

いろいろと勉強になりました。

602 名前:デフォルトの名無しさん :04/01/06 08:19
>>601
Intel(R) Visual Fortran と Visual C++ との連携がいいのでは?
http://www.xlsoft.com/jp/products/intel/compilers/iftnwin.html
6万円以上するから無理には薦めないけど。

603 名前:デフォルトの名無しさん :04/01/06 08:24
そういや、>>515 で、
test 呼ぶときにも FNAME 使うのを忘れてたな。

604 名前:デフォルトの名無しさん :04/01/06 12:48
for(i=0;i<1000;i++){
cout << i << "," << a[i] << endl;
}

みたいなプログラムがあったとして、実行結果が1000行になってしまうので
DOS窓では見られません。(WinMeです)
テキストにするにはどうしたらよいでしょうか。

605 名前:デフォルトの名無しさん :04/01/06 12:55
リダイレクト

606 名前:デフォルトの名無しさん :04/01/06 12:56
>>604 リダイレクト

607 名前:デフォルトの名無しさん :04/01/06 12:58
リダイレクト > リダイレクト

608 名前:デフォルトの名無しさん :04/01/06 15:45
>>604
c:\hoge > output.txt

これでoutput.txtに出力される。

609 名前:デフォルトの名無しさん :04/01/06 17:18
>>605-607
ワラタ

>>604
608のような方法で
コマンドの標準出力を
テキストファイルに出力することを
リダイレクト、っていう。

610 名前:デフォルトの名無しさん :04/01/06 18:25
C:\> hoge | more

611 名前:デフォルトの名無しさん :04/01/06 19:10
>>610
パイプ

612 名前:デフォルトの名無しさん :04/01/06 20:16
vector<string>のなかからstring::empty()==TRUEのものを削除したくて
以下のようにしましたが、エラーが出ます

s.erase(
  std::remove_if(s.begin(),
     s.end(),
     std::mem_fun_ref(&std::string::empty)),
  s.end);

c:\my documents\my project\vc\mysources\dnabbandex\commonaccess.cpp(221) : error C2664: 'mem_fun_ref' :
1 番目の引数を 'bool (__thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::*' から。。。

どのようにすればいいのでしょうか?
お願いします。



613 名前:デフォルトの名無しさん :04/01/06 21:39
>>612
最後の s.end を s.end() にしてもダメ?

614 名前:デフォルトの名無しさん :04/01/06 22:11
>>612
VC6だよね?const_mem_fun_ref_t とかが用意されてないので
const メンバ関数に mem_fun は使えなかった記憶がある。
VC.NET 2003 なら通ったっす。

615 名前:612 :04/01/06 22:33
>613,614
ありがとうございます。

おっしゃるようにVC6の問題のようです。gccでもとおりました。

616 名前:デフォルトの名無しさん :04/01/08 23:21
型Tについて、例外値を持たせたい。
ポインタで言うところのヌルポインタのように。

template<typename T>
class Holder {
 public:
  Holder(T v) : _valid(true), _v(v) {}
  Holder() : _valid(false) {}

  bool isValid() const {return _valid};
  T &getValue() const
  {
   if (!_valid) throw 例外;
   return _v;
  }

 private:
  bool _valid;
  T _v;
};

他にいい方法ありますでしょうか?


617 名前:sune :04/01/08 23:32
スマートポインタにして例外はヌるポで代用


618 名前:デフォルトの名無しさん :04/01/08 23:42
依存関係にある型限定子とはどのようなものを指すのでしょうか?
教えてください


619 名前:デフォルトの名無しさん :04/01/08 23:46
>>616
boost::optional。いや、やってることは本質的にキミのコードとあまり変わらんけど。

620 名前:デフォルトの名無しさん :04/01/09 01:00
>>616
ポリシークラスで、例外値を定義する。

621 名前:デフォルトの名無しさん :04/01/09 01:10
基本クラスでデストラクタを、virtual指定すると、
その派生クラスのデストラクタはすべて仮想関数になるんですか?

622 名前:デフォルトの名無しさん :04/01/09 01:12
はい

623 名前:デフォルトの名無しさん :04/01/09 01:12
>>621
単一継承する限りはな。

624 名前:デフォルトの名無しさん :04/01/09 02:04
inline関数にするのとしないのではどうちがうのですか?
ヘルプを読んでもよくわからないのでinlineって使ったことないんですけど
なんかまったく困らないのでどうでもいいのでしょうか?

625 名前:デフォルトの名無しさん :04/01/09 03:09
>>624
一般的にはどうでもよくないけど、
君にとってはどうでもいいよ。

626 名前:デフォルトの名無しさん :04/01/09 03:17
C では単純な処理の場合、呼び出し時間が無駄だからって
関数の代わりにマクロという厄介なものを使うことがあったけど、
C++ ではそれを回避するために inline 関数が導入されたんだよ。

627 名前:デフォルトの名無しさん :04/01/09 03:18
gcc だったら -O3 option をつければ inline とほぼ同じになるんだっけ?

628 名前:616 :04/01/09 03:38
>>617-620
ありがとうございます。
あながち的はずれなコードではないことが判っただけでも安心しました。


629 名前:デフォルトの名無しさん :04/01/09 06:17
>627
実装が翻訳単位にあればそうかもしれないけど
(ヘッダファイルとかさ)
なければ普通は最適化オプション程度でのinline化は無理では。

630 名前:デフォルトの名無しさん :04/01/09 09:48

UNIX(LINUX)で、永久ループをする常駐物を作っています。

clockで時間を計測して正確に200ms毎に実行したいのですが、
どうすれば良いのでしょうか?

sleep()は1秒単位ですし、selectをつかうとすぐに結果が返ってきてしまいます。
ms単位のsleepって無いんでしょうか?


631 名前:デフォルトの名無しさん :04/01/09 09:50
書き忘れました。
からループとかを使えばすぐにできるのですが、
マシンパワーを使わないようにするためにsleep等を使いたいのです。


具体的な処理内容は、socket接続の待機と、socketの受信データによる挙動です。



632 名前:デフォルトの名無しさん :04/01/09 09:51
>>630
nanosleep(2), usleep(3)

633 名前:デフォルトの名無しさん :04/01/09 09:53
>>631
でもsocketの待機になんでsleep+ポーリングなんかするんだ?
よっぽど大量のソケット回すのか

634 名前:633 :04/01/09 09:55
書き忘れたけど、スレッド分けてブロックする手をなぜ使わないのかってことね

635 名前:デフォルトの名無しさん :04/01/09 10:15
>632
投稿した直後、さらにぐぐってusleep()を発見しました。
でもありがとう。

はじめにぐぐったら、
sleepは1秒単位なので、ms単位の待機ならselectを使え!みたいなWebがあったので、
変なハマりかたをしてしまった。

>633

秒間x回、
1、ゲームサーバーとしての挙動(物理演算とか)
2、新規接続の確認
3、clientからのデータの処理

同人ゲーム作ってるってかくの、なんか気が引けました。
ここから1を抜いたので変な質問になりました、すみません。



636 名前:デフォルトの名無しさん :04/01/09 10:33
ていうかC++の質問になってませんよ

637 名前:デフォルトの名無しさん :04/01/09 14:57
BlitzやMTLなどのライブラリを使いたいんですけど
どこかに日本語による詳しい解説でもないでしょうか。

638 名前:sage :04/01/09 17:05
いい機会だから英語を覚えなさい

639 名前:デフォルトの名無しさん :04/01/09 18:46
bccでコンパイルしたプログラムのファイルサイズを46kbぐらいより小さくする方法ってありますか?
UPXを試してみたけどエラーで起動しなくなるし...。

640 名前:sage :04/01/09 19:17
スタートアップコードを自前で用意しなさい

641 名前:デフォルトの名無しさん :04/01/09 19:30
>>639
環境によるだろ。
俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力
ランタイムを使用するようにして使っているが、例えばstd::vectorを
使っても使わない時と比べ10Kほどしか増えない。

642 名前:デフォルトの名無しさん :04/01/09 19:47
>>641
>環境によるだろ。
タワラ

643 名前:デフォルトの名無しさん :04/01/09 20:51
>>641
某スレで見た覚えのあるレスだな
コピペか?

644 名前:デフォルトの名無しさん :04/01/09 21:04
>>641
すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。

645 名前:デフォルトの名無しさん :04/01/09 21:16
懐かしいなぁ、もう。

646 名前:デフォルトの名無しさん :04/01/10 05:52
C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
とかいうエラーが出るんだけどこれってどうすればいいの?

647 名前:デフォルトの名無しさん :04/01/10 05:52
>>646
#include <stdafx.h>

後死ね。

648 名前:デフォルトの名無しさん :04/01/10 05:54
>>647
言葉が悪いな。それで教えているつもりか。
まぁヒントぐらいにはなったな。
うむごくろう。

649 名前:639 :04/01/10 09:10
>>640
スタートアップコードって?という状態だから諦めろ、ってことなんだろうな…。
bccの中の人がでっかい張りぼてを用意した所為、って理解で良い?

650 名前:デフォルトの名無しさん :04/01/10 10:09
>>647
#include "stdafx.h"

651 名前:デフォルトの名無しさん :04/01/10 10:25
>>639
エクストリームな小ささを求める場面(実際ある)はアセンブラの出番
リンカの定義ファイルも自分で書いて細部にわたって贅肉を落とすべし

スレ違いすまそ

652 名前:デフォルトの名無しさん :04/01/10 20:19
土日、祝日になるとただでさえ少ないレスが0になるよね・・・。


653 名前:デフォルトの名無しさん :04/01/10 21:11
>>651
TClockの作者さんがNASMでスタートアップルーチンを指定する方法を解説していたのを思い出して
読んでみた、が、やはりちんぷんかんぷん…。

実行ファイルのサイズを小さくする
ttp://homepage1.nifty.com/kazubon/progdoc/tclock/nodeflib.html


654 名前:デフォルトの名無しさん :04/01/10 22:33
>>652
なんか最近さびれちゃったね。
それとは対照的になんか cppll が最近活発になってるし、
ここの住人がアッチへ逝っちゃったのかのなぁ?

655 名前:デフォルトの名無しさん :04/01/10 23:35
>>654
最近cppllの話題の質が下がってきたと思っていたが、
そういう事だったか・・・・

656 名前:デフォルトの名無しさん :04/01/10 23:36
じゃあ俺もあっちに参加できるかな

657 名前:デフォルトの名無しさん :04/01/11 00:12
>>656
cppll_novice へどうぞ。
http://jbbs.shitaraba.com/bbs/read.cgi/computer/5651/1073472670/

658 名前:デフォルトの名無しさん :04/01/11 02:36
>>657
cppllの質の低下を危惧した某氏が隔離MLとして作ったと
思わるる。

659 名前:デフォルトの名無しさん :04/01/11 09:42
次のような定義だったら…

class TYPEA{
〜〜
};
class TYPEB:public TYPEA{
〜〜〜
};

TYPEB varB;
//------------------------------

(1)varBがTYPEBのインスタンスである事を調べる関数はありますか?
(1)varBがTYPEAから派生した型のインスタンスである事を調べる関数はありますか?

660 名前:デフォルトの名無しさん :04/01/11 09:56
>>659
関数オーバーロードやテンプレート引数のマッチングルールを利用するテクニックはあるが

661 名前:デフォルトの名無しさん :04/01/11 10:59
>>659
何らかのフレームワークに沿って実装するか、処理系依存の機能を利用しない限り、
C++の言語仕様のみでは無理かと。


662 名前:デフォルトの名無しさん :04/01/11 11:09
dynamic_castは?

663 名前:デフォルトの名無しさん :04/01/11 11:17
>>659
typeid(varB) == typeid(TYPEB)
dynamic_cast<TYPEA*>(&varB) != NULL

ただしTYPEAやらTYPEBやらに仮想関数が存在することが前提。

664 名前:デフォルトの名無しさん :04/01/11 12:17
>>661
>C++の言語仕様のみでは無理かと。

RTTIについては662,663に先に言われてしまったが
仮にそれを知らなかったにしても
せめてこのくらい思いつけよ

class TYPEA {
//...
virtual const char* kind() const;
};
// ...
const char* TYPEA::kind() const { return "TYPEA"; }
const char* TYPEB::kind() const { return "TYPEB"; }

665 名前:デフォルトの名無しさん :04/01/11 12:37
>>664
>>661
> 何らかのフレームワークに沿って実装するか、


666 名前:デフォルトの名無しさん :04/01/11 12:38
型情報が失われたポインタですら簡単に判定できる

class TYPEA {
private:
static std::list<const void*> objects;
public:
TYPEA(); // register
~TYPEA(); // unregister
static bool isTYPEA(const void*); // search
};

処理系に依存しない「C++の言語仕様のみ」でどうにでもなるyo

667 名前:デフォルトの名無しさん :04/01/11 12:43
多重継承にはpairが要りそう

668 名前:デフォルトの名無しさん :04/01/11 12:49
typeidは標準だけどな

669 名前:デフォルトの名無しさん :04/01/11 12:53
>>666
>>661
> 何らかのフレームワークに沿って実装するか、

670 名前:デフォルトの名無しさん :04/01/11 13:07
ところで共通の配列に属さないポインタを比較しても良いの?

671 名前:デフォルトの名無しさん :04/01/11 13:08
>>670
大小関係は意味ないが、一致・不一致判別にはよく使う

672 名前:デフォルトの名無しさん :04/01/11 14:38
> 一致・不一致判別にはよく使う
その結果を仕様として定義されているのは NULL との比較だけだったと思ったが。
たとえば Intel 8086 用のコンパイラにおける far pointer 同士の比較が相当する。


673 名前:デフォルトの名無しさん :04/01/11 14:38
>>670
規格上は、良くない。less<T*>::operator() を使う。

674 名前:デフォルトの名無しさん :04/01/11 15:04
>>672
8086でのfar pointerのように同一アドレスを表す表現が沢山あるものは
正規化しない限り同一性の比較も正しくできなかったな。

でも、規格(ISO 14882-1998)では...
5.10 - Equality operators [expr.eq]の-1-
>...Pointers to objects or functions of the same type (after pointer
>conversions) can be compared for equality. Two pointers of the
>same type compare equal if and only if they are both null, both
>point to the same object or function, or both point one past the
>end of the same array.
うーん、この文の中では同一オブジェクトへのポインタ同士はequalだと
書かれているが・・。

675 名前:デフォルトの名無しさん :04/01/11 15:14
>>672
5.10 Equality operators の 1
> Pointers to objects or functions of
> the same type (after pointer conversions) can be compared for equality. Two pointers of the same type
> compare equal if and only if they are both null, both point to the same object or function, or both point one
> past the end of the same array.
比較演算に関しては確かに不定と書いてあるんだが、==, != に関しては問題なさげ。

あと現実問題としてリニアなメモリモデルが主流になっているから、よほど特殊な
環境に移植するのでなければ、その辺は気にしなくて良いと思われ。far ポインタ
とか言いだした段階で既に処理系依存の拡張機能だしさ。

676 名前:デフォルトの名無しさん :04/01/11 18:39
>>673
詳細きぼん

677 名前:デフォルトの名無しさん :04/01/11 21:30
>>676
違うオブジェクト/配列を指すポインタ同士の大小比較は
実装はともかく規格上では unspecified なのだが、
less とか greater とかのテンプレート だと、20.3.3 Comparisons:
> 8 For templates greater, less, greater_equal, and less_equal, the spe-
> cializations for any pointer type yield a total order, even if the
> built-in operators <, >, <=, >= do not.
正しく全順序がつく( (p<q && q<r) == true なら (p<r) == true になる、etc... )
ことが定められている。っちうこと。

678 名前:デフォルトの名無しさん :04/01/11 21:37
>>677
比較の最中に大小順が逆転しないことが保証されてるってことか?
だったらlessでも<でも同じで>>670に対して何が言いたかったのか
やっぱりわからん

679 名前:デフォルトの名無しさん :04/01/11 22:20
>>678
< では保証されてない。less では保証されている。

680 名前:679 :04/01/11 22:26
あー、何で混乱させてしまったのかがわかった。書きたかったのは
> 正しく全順序がつく( (p<q && q<r) == true なら (p<r) == true になる、etc... )
じゃなくて
> (less<T*>()(p,q) && less<T*>()(q,r)) == true なら less<T*>()(p,r) == true
だ。スンマソン.

681 名前:デフォルトの名無しさん :04/01/12 04:03
>>679
未規定な大小順が逆転しないことの保証に何の意味がある?
まさか等値非等値が逆転しないことと混同してないよな。

682 名前:デフォルトの名無しさん :04/01/12 04:04
>>670に対して何が言いたかったのかやっぱりわからん

683 名前:デフォルトの名無しさん :04/01/12 04:07
StrictWeakOrdering?

684 名前:デフォルトの名無しさん :04/01/12 04:42
>>659
(1)まあ663のようにRTTIを使うという手もあるけど、これだと仮想関数とRTTIなしで実現できる。まあ必要性薄いけど。

template <typename T>
struct IsTYPEBImpl{
    enum{value=0};
};
template <>
struct IsTYPEBImpl<TYPEB>{
    enum{value=1};
};
template <typename T>
bool IsTYPEB(const T & arg){
    return IsTYPEBImpl<T>::value!=0;
};

(2)はLokiのSUPERSUBCLASSやboostのtype_traitsのis_base_and_derivedあたりが使えるかな、ただしコンパイラ選ぶけど。


685 名前:684 :04/01/12 04:56
追記
参照とポインターの参照先については正しく動かないので注意が必要。
そういう場合は素直にRTTI使った方が吉。
template関数の引数の型調べたりとかには使えるけど。


686 名前:デフォルトの名無しさん :04/01/12 05:32
いきなりレベルが低くなってすまんのだがCだと
fp = fopen(file, mode == read? "rb": "wb");
という感じで簡単に読み込み方法をasciiとbinaryを書き換えられるんだけど
これをC++風にするとどうなるの?

687 名前:デフォルトの名無しさん :04/01/12 05:47
>>686
それはバイナリモードか否かでなくて、読み込み用か書き込み用かを切り替えてると思うが。
その後の操作考えると壮絶に意味がないんじゃないか?

それはさておきC++なら
std::ifstream hoge(filename, is_binary ? std::ios_base::binary : 0):


688 名前:686 :04/01/12 05:50
>>687
質問の意味すら違ってくる致命的ミスなのに優しくフォローありがd。

689 名前:679 :04/01/12 08:36
>>681
その保証があるおかげで、例えば std::set<T*> や std::map<T*> が
正しく動作することが保証される。物凄く意味のある保証ではなかろうか。

>>682
> ところで共通の配列に属さないポインタを比較しても良いの?
に対して、「< が < っぽく振る舞うことを期待するなら、異なる配列に
属するポインタを < で比較しちゃいけない」と言いたかっただけなんだが。

比較は比較でも等値比較 ==, != は問題ないってのは他の皆さんが書いたとおりだし、
最悪、例えば共通の配列に属さない配列を比較したら常にtrueが返るという
実装でもいいなら、 <, >, <=, >= で比較してももちろん構わない。

# 何回も書いてるように、<,>,<=,>= がうまく機能しないような実装は、
# "現実には"ほぼ存在しないと思って問題ないだろうけどね。

690 名前:デフォルトの名無しさん :04/01/12 08:39
×共通の配列に属さない配列
○共通の配列に属さないポインタ

691 名前:デフォルトの名無しさん :04/01/12 09:27
(1) T hoge = 0; と
(2) T hoge = T(0); って

T hoge(0); と同義になるんじゃなかったでしたっけ?
(2)の書き方するとコピーコンストラクタが呼ばれちゃうんですけど


692 名前:デフォルトの名無しさん :04/01/12 09:31
>>691
(3) T hoge(0);
(1)と(3)が同じなだけかと

693 名前:デフォルトの名無しさん :04/01/12 09:50
>>692
(1)もコピーコンストラクタ呼ぶです(mingw)。

694 名前:デフォルトの名無しさん :04/01/12 10:10
こっちでは普通のコンストラクタが呼ばれるがなぁ。 > MinGW

695 名前:デフォルトの名無しさん :04/01/12 10:17
#include <iostream>
using namespace std;

class A {
public:
 A() { cout << "A" << endl; }
 A(int a) { cout << "int " << a << endl; }
 A(const A& a) { cout << "Copy" << endl; }
};

int main() {
 A a = 0;
}

出力 (MinGW's g++ 3.2)
int 0

出力 (Cygwin's g++ 3.2)
int 0

出力 (VC++ 7.0.9486)
int 0

696 名前:デフォルトの名無しさん :04/01/12 10:39
>>694
コピコンよばれちゃいます。
コンパイル通りません。
template
<
 typename T,
 typename SrcPointerType = T*
>
class CMustAssignedPointer
{
 private: typedef CMustAssignedPointer ThisType;
 private: SrcPointerType m_SrcPointer;
 private: CMustAssignedPointer();
 public: CMustAssignedPointer(const ThisType& rhs)
  : m_SrcPointer(rhs.m_SrcPointer)
 {
 }
 public: CMustAssignedPointer(SrcPointerType rhs)
  : m_SrcPointer(rhs)
 {
 }
};

int main()
{
 int* p = NULL;
 std::auto_ptr<int> p2(new int(100));

 CMustAssignedPointer<int> pNum = p;
 CMustAssignedPointer<int, std::auto_ptr<int> > pNum2 = p2;
}

697 名前:デフォルトの名無しさん :04/01/12 10:41
コピコンが呼ばれてコンパイルが通らない理由は
std::auto_ptrのコピコンが非constのrhsを要求するからだというのは
わかってるんですが…
CMustAssignedPointer(SrcPointerType rhs)
でそれを回避したいのです。

698 名前:デフォルトの名無しさん :04/01/12 12:35
>>689
setやmapで必要になるのは等値非等値か指し示す先の比較やん。
670に対して何を言おうとしたのかはなんとなく見えてきたが到底賛同できるものではないな。

699 名前:デフォルトの名無しさん :04/01/12 12:58
たとえばintを戻す関数ポインタを引数に取る関数があるとします。
void foo(int funcptr());
普通の関数int bar() {return 0;}の場合は、foo(bar)で関数ポインタを渡せます。
ここにメンバ関数の関数ポインタを渡すことはできるのでしょうか?
class Foo {
public:
 int bar() {return 0;}
};
のクラスの場合、fooに渡す引数にはどう書けばよいのでしょうか?

700 名前:699 :04/01/12 13:00
すみません、ちょっと追加。
int main()
{
 Foo* f = new Foo();
 foo(??);
}
のときの"??"の部分にどう書くかという質問です。

701 名前:デフォルトの名無しさん :04/01/12 13:13
>>699
なにをどうやっても非staticなメンバ関数を通常の関数ポインタに渡すのは不可能。

702 名前:デフォルトの名無しさん :04/01/12 13:22
>>699
そのままでは無理です。メンバ関数ポインタは普通のポインタとは区別されます。
解決策1:fooを多重定義orテンプレート化(fooを変更できて、且つfooが複数になってもかまわない場合)
    void foo(int (Foo::*fun)());
    template <typename Fun>
    void foo(Fun fun);
2:汎用のファンクタを利用する(fooを変更できる場合)
    void foo(boost::function<int ()> fun);
3:Foo::barをstaticにする(barがFooの非staticメンバにアクセスしない場合)
4:Fooのインスタンスを名前空間レベルで保持する(最後の手段)
    Foo f;
    int foo_bar() {return f.bar();}
この場合、foo_barをfについてテンプレート化することで、冗長なコードを記述しないで済ませられます。

703 名前:699 :04/01/12 14:11
>>701-702
早速の回答、ありがとうございました。
staticにすればfoo()に渡せるのは解っていたのですが、Foo::bar()内でメンバ変数(インスタンス変数)に
アクセスしたかったのです。
foo()というのは、callbackの登録をするための関数で、提供されたライブラリ内にあり変更できません。

正直>>702の内容は、3を除いてあまりよく理解できないのですが「非スタティックなメンバ関数を
通常の関数ポインタに渡すのは不可能」ということがわかっただけでも大きな収穫です。
今までどうにかしてキャストしようとして悪戦苦闘していたもので・・・。

702さんの情報をもとに、さらなる勉強をしようと思います。
ありがとうございました。

704 名前:699 :04/01/12 14:14
多分僕にはvtptrなどのC++のメカニズムに関する知識が欠けているので、このような問題に
対応できないのだということを思い知らされました。

705 名前:699 :04/01/12 14:19
あぁぁ、すみません。独り言を書き込もうとして、途中でやはりやめようとしたんですが、
間違って書き込みしてしまいました。
スレを汚してすみませんでした。

706 名前:デフォルトの名無しさん :04/01/12 14:27
>>704
一応解説してみたり。
非staticなメンバ関数を呼ぶには
関数のアドレスだけでなく、(thisになる)オブジェクトのアドレスもまた必要。
この二つが揃って初めて呼び出しが許される。

で、メンバ関数ポインタ型としてメンバ関数のアドレスを単独で取り出した場合
"->*"や".*"演算子でオブジェクトとくっつけない限り呼び出せない。

ただ、間接的に扱うときにこの二つのデータをバラバラに扱うのは面倒なので、
ひとつにまとめて運ぶ手段としてよく使われるのが関数オブジェクト(ファンクタ)。

707 名前:デフォルトの名無しさん :04/01/12 14:33
食生活で顎の発達が阻害されて歯の生える場所がないからだが、
場所自体が無いのに矯正だけで直るものなの?
やっぱり場所確保のために歯を何本か抜いちゃうの?

708 名前:デフォルトの名無しさん :04/01/12 14:36
>>704
推薦図書

ISBN4-8101-8101-4

709 名前:デフォルトの名無しさん :04/01/12 14:49
void foo(int callback(void*), void* data);
みたいになってれば間接的にメンバ関数呼べるんだがな。

710 名前:699 :04/01/12 15:06
うぅぅ、皆さんどうもありがとうございます。
2chでこんな優しい人たちに会ったの初めてです(感涙

>>708 早速今から秋葉の書泉に買いに行ってきます。

>>709
なってます。後出しの情報ですみません。
ライブラリは一度クライアントコードの
void baz(void** buf, size_t size, void** handle)
というのを呼び出します。bazでは
baz(void** buf, void* handle)
{
 *buf = new unsigned char[size];
*handle = 任意のポインタ
}
とかできます。そのbufにライブラリは値を設定して、handleとともにコールバックしてきます。
このvoid baz()はstaticで全然かまわないんですが、bazの中でnew Foo()したかったんです。

と、ここまで書いて、callbackの設定はbazの外側でやるのだから、new Foo()したポインタは
使えないということですよね。なんか、混乱しまくってます。
もうちょっと自分でよく考えて見ます。

711 名前:デフォルトの名無しさん :04/01/12 15:10
連続書き込みですみません。
fooとかbarとか使うから良くわからない書き込みになってるんですよね。
これらの仕様書は会社にあって今手元に無いので、明日会社に行って、
いろいろ試してから、再度質問する場合は、それらしい名前に変えて書き込みます。
(できる限り自己解決するつもりです)

712 名前:デフォルトの名無しさん :04/01/12 15:21
柴田望洋著の「C++プログラミング言語」の演習問題解答のソースプログラム持っている人いませんか?
listのソースは後援ページからダウンロードできるんですが、演習問題の解答がなくて困っています。
「例解演習」の方も買いましたが、微妙に違うところがあります。
学校で習っているのですが、提出期限に間に合わなくて。。。。
知っている方教えてください。

713 名前:デフォルトの名無しさん :04/01/12 15:22
class Foo
{
public:
 static int callback(void* ptr)
 {
  return reinterpret_cast<Foo*>(ptr)->finc();
 }
 int func();
};

Foo* obj = new Foo;
foo(Foo::callback, reinterpret_cast<void*>(obj));

C++でコールバック関数使うときの定番。まぁ、callbackは独立した関数でもいいんだが。

714 名前:デフォルトの名無しさん :04/01/12 15:25
>>698
> setやmapで必要になるのは等値非等値か指し示す先の比較やん。

「等値非等値か指し示す先の比較」ってなに?
==,!= のこと?

715 名前:デフォルトの名無しさん :04/01/12 15:46
#include <stdio.h>
void main()
{
  printf ("\t\b\b");
}

w2kでこれやると落ちると聞いたんですが本当ですか?環境がなくて試せませぬ

716 名前:デフォルトの名無しさん :04/01/12 15:55
>>715
スレ違い

そんなカビの生えたコードを今頃見つけて喜んでる知障は氏ね

717 名前:デフォルトの名無しさん :04/01/12 16:54
C++(iostream)でfseekにあたるのは何ざましょ?

718 名前:デフォルトの名無しさん :04/01/12 16:54
>>714
たぶん、

 set<int*>

と使うにせよ「ポインタ値の代償ではなく、実際の int 値の代償でソートするように
関数オブジェクトつくって渡すのがふつーだろ」と言いたいんじゃないの?

ポインタ値でソートしたいこともあるけどなぁ。生ポインタをそのまま使わず、Windows
の HANDLE みたいにラップした値を返して使うようなフレームワークを作るときに、
HANDLE <-> 生ポインタ相互変換部分を map で書くとかさ。

719 名前:679 :04/01/12 16:57
>>698
> setやmapで必要になるのは等値非等値か
ワシは等値非等値って == と != の結果のことだと理解していたんだが、
setやmapにそれは必要ない。どういう意味でその用語を使ってるか
説明してくれると嬉しい。
> 指し示す先の比較やん。
set<T> でなくて set<T*> よ?指し示す先を比較してどうする?

720 名前:デフォルトの名無しさん :04/01/12 16:59
>>717
seekgとseekp

721 名前:デフォルトの名無しさん :04/01/12 18:43
こんな風になるかなぁ
#include <iostream>
class Foo
{
public:
void foo(){ std::cout << "Foo::foo" << std::endl; }
};
void func(void (Foo::*memFunPtr)(), Foo &f)
{
(f.*memFunPtr)();
}
int main()
{
Foo f;
func(Foo::foo, f);
return 0;
}


722 名前:デフォルトの名無しさん :04/01/12 18:52
>>719
equality と equivalent の訳語の話か? それだと人によって用語がマチマチだから、
C++ の規格書通りの英単語を使った方が良いかもしれん。

723 名前:デフォルトの名無しさん :04/01/12 19:00
もうその話題はいいって

724 名前:アルティメット ◆17Hz8gAKSA :04/01/12 20:42
初めまして皆さん
自分は専門学校の情報処理科2年制に勤めているアルティメットと言います
実はかれこれ1年近くいるくせにC言語プログラミングを全く理解していません
何度か真面目に理解しようとしたのですがちっともわかりません
最後の手段として2chに頼ろうと思います
皆さんよろしくお願いします

725 名前:デフォルトの名無しさん :04/01/12 20:45
カエレ

726 名前:デフォルトの名無しさん :04/01/12 20:45
>>724
嫌です。すぐに進路を変更して下さい。

727 名前:デフォルトの名無しさん :04/01/12 20:45
>>724
いろんな意味でスレ違い

728 名前:アルティメット ◆17Hz8gAKSA :04/01/12 20:56
いえいえ
頑張って理解しようと思うので
どうか大目に見てやってください
頼みます

729 名前:デフォルトの名無しさん :04/01/12 21:00
>>724
2chに頼ることの是非はともかくとして、お前は何をして欲しいんだ?

730 名前:デフォルトの名無しさん :04/01/12 21:00
カエレッツッテンダロ

731 名前:デフォルトの名無しさん :04/01/12 21:01
ワラタ

732 名前:アルティメット ◆17Hz8gAKSA :04/01/12 21:03
そうですねぇ
C++で出来る範囲の問題を出してみてくれます?
なんとか解いてみせますので

733 名前:デフォルトの名無しさん :04/01/12 21:05
>>732
よし、ここに逝け。
http://pc2.2ch.net/test/read.cgi/tech/1073566342/

734 名前:アルティメット ◆17Hz8gAKSA :04/01/12 22:24
とりあえず今わかるのが
printf 文字列表示
int 整数定義
char 文字数定義
float 浮動小数点数定義
%d 整数表示
%f 小数表示

このぐらいなんですよ

735 名前:デフォルトの名無しさん :04/01/12 22:29
学習1日目か。先は長いぞ。
とりあえず入門書1冊とK&R読み終えてからまた来い。

736 名前:デフォルトの名無しさん :04/01/12 22:32
ここはC++なのでK&R読んだからって来られても迷惑なんだが。
C++3rdならともかく。

737 名前:デフォルトの名無しさん :04/01/12 22:47
>>719
おまえもひつこいな
set<T*>での同一配列に属さないオブジェクトへのポインタの等値非等値でない大小比較に何の意味がある?
意味があるかどうかではなくコンパイル通ったってだけな議論ならそろそろ見限るぞ

738 名前:デフォルトの名無しさん :04/01/12 23:05
>>734
cppll_novice へどうぞ。
http://jbbs.shitaraba.com/bbs/read.cgi/computer/5651/1073472670/

739 名前:デフォルトの名無しさん :04/01/12 23:31
>>737
> set<T*>での同一配列に属さないオブジェクトへのポインタの等値非等値でない大小比較に何の意味がある?
上で誰か書いて他が、ポインタを生で見せるのは嫌だから汎用のハンドルクラスを
作りたいとか。クライアントには THandle だけ見せて、T* は一切見せないようにする。
Windows の HWND とかUNIX のファイルデスクリプタなんかと同じように。

STL で書くと、こんな感じになると思うが。

template <class T, class THandle>
class HandleManager {
public:
  T* getPtr(THandle h);
  THandle register(T* p);
  void remove(T* p);
private:
  std::map<T*, THandle> p2h;
  std::map<THandle, T*> h2p;
};

まぁ、俺なら STLport 入れて hash_map 使うけど。

740 名前:デフォルトの名無しさん :04/01/12 23:32
>>737
719ではないが、
大小比較ができなければ、そもそも set<T*> を作れない。
ポインタに対して大小比較ができること(less<T*>が定義されていること)が本質的。

たとえば、
typedef void* HWND;
のような定義がされている場合に、
set<HWND>を実現するためには less<HWND>が定義されていなければならない。
すなわち less<void*>が安定して計算できる必要がある。


741 名前:679 :04/01/12 23:39
>>737
だから説明してあげるから、その"等値"という用語の、キミの使っている
定義を教えて下され。申し訳ないが、「等値非等値でない大小比較」の意味が
ワシには理解できてないので、それに何の意味があるのかは説明できない。

一応とこっちの主張をまとめさせてもらうと、
ワシのしたい主張は 「less<T*>() を使った比較なら、同一配列に属さない
ポインタも含めて全順序(total order)になることが保証されている。」 だけだ。それに
> 何の意味がある?
と問われれば、何回か書いたように、「この保証のおかげで、set<T*> や
map<T*> に同一配列に属さないポインタを放り込んでも正しく動作する
ことが保証されるので、嬉しい」という意味がある。もっと具体的に書いた
方がわかりやすければ、例えば>>718氏のあげた例:
 map<HWND, CWindow*> hwnd_to_wndptr_map;
 map<CWindow*, HWND> wndptr_to_hwnd_map;
のようなmap<>の使い方ができる、ということ。

# 「正しく動作する」 というのは、入れたはずのポインタがいつの間にか
# 消えてなくなったり、逆にコンテナから削除したはずなのにまだ残ってたり…
# などなどの怪しげな動作をせずに動く、ってこと、と思ってくれ。

742 名前:679 :04/01/12 23:40
あー、かぶった。。。

743 名前:696 :04/01/13 00:01
流れ流され〜

template
<
 typename T,
 typename SrcPointerType = T*
>
class CMustAssignedPointer
{
 private: typedef CMustAssignedPointer ThisType;
 private: SrcPointerType m_SrcPointer;
 private: CMustAssignedPointer();
 public: CMustAssignedPointer(const ThisType& rhs)
  : m_SrcPointer(rhs.m_SrcPointer)
 {
 }
 public: CMustAssignedPointer(SrcPointerType rhs)
  : m_SrcPointer(rhs)
 {
 }
};

int main()
{
 int* p = NULL;
 std::auto_ptr<int> p2(new int(100));

 CMustAssignedPointer<int> pNum = p;
 CMustAssignedPointer<int, std::auto_ptr<int> > pNum2 = p2;
}

なんでコピーコンストラクタが呼ばれちゃうんでしょうか?

744 名前:デフォルトの名無しさん :04/01/13 00:01
>>740
だから、そんなもの作れたからって、何になる?
繰り返すが、意味があるかどうかではなくコンパイル通ったってだけな議論ならそろそろ見限るぞ

>>741
もしかして map<CWindow*, HWND>::iterator の大小比較が HWND の大小比較とでも思っているのか?

======================================

>入れたはずのポインタがいつの間にか
># 消えてなくなったり

( ´,_ゝ`)プッ
それじゃ定義を教えても理解できそうな御仁に見えないよ

745 名前:デフォルトの名無しさん :04/01/13 00:16
>>743
いろいろまずそうなところを弄ったけど、
どうやっても何故かコピーコンストラクタが選ばれるっぽい
(そしてコンパイルに失敗する)。
コンパイラのバグかも?

746 名前:デフォルトの名無しさん :04/01/13 00:25
>>744
逆だな。
おまえを見限った。


747 名前:739 :04/01/13 00:28
>>744
> だから、そんなもの作れたからって、何になる?
739 で実例を挙げてるが
> std::map<T*, THandle> p2h;
こういう、ポインタをキーとしてハンドル値を引きたい場合に困るっつー話。
ま、お互い言うべきことは言ったと思うから、この辺で終わりにしましょうか>みなさん

まとめ

1. C++ の規格では、同一配列に属さないポインタは ==, != で比較することはできるが、
 <, <=, >, >= で比較した時の結果は未定義。
2. ただし、現実にはフラットなメモリアドレッシングを採用したアーキテクチャが主流なので、
 ほぼ全ての C++ 処理系で <, <=, >, >= でもポインタ間に全順序関係をつけられる。
3. C++ では <, <=, >, >= で順序関係をつけられないアーキテクチャも考慮して、ポインタ値を
 比較した場合に全順序関係が成立しない場合でも、std::less<T*>, std::greater<T*> を
 使えば全順序関係が成立するように規定している。

748 名前:デフォルトの名無しさん :04/01/13 00:55
単にSTLの内部でoperator<を使ってないってだけの話だろ
引数が組み込み型かどうか判定する機能がtemplateにないからって真意で

747の言うべきこととやらが何なのかいまだに不明だが
言葉遊びが終わったならこっちも相手しつづける理由はない

749 名前:デフォルトの名無しさん :04/01/13 01:03
>>744
>もしかして map<CWindow*, HWND>::iterator の大小比較が HWND の大小比較とでも思っているのか?

iteratorと大小比較は直接関係ないでしょう。
map<CWindow*, HWND>に必要なのはCWindow* の大小比較と思っていますが、それが何か。


750 名前:デフォルトの名無しさん :04/01/13 01:03
>>748
なんでオマエは自分の馬鹿さ加減をそんなに宣伝したいのだね?
見てて面白いからいいけどさ。


■過去ログ置き場に戻る■ 1- 前250 次250 最新50
DAT2HTML 0.33f Converted.