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


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

C++相談室 part27
501 名前:デフォルトの名無しさん :04/02/13 17:55
>>499
リダイレクトしてファイルに落としてから見る。

502 名前:デフォルトの名無しさん :04/02/13 18:29
>>499
MOREに似非パイプでつないで見る。

503 名前:デフォルトの名無しさん :04/02/13 18:43
>>499
DOS 窓のバッファサイズを大きくする。

504 名前:デフォルトの名無しさん :04/02/13 19:01
cygwin上でなら

$ gcc ..... 2>&1 | less

MSYS は知らん。

505 名前:デフォルトの名無しさん :04/02/13 19:03
というかemacs使うと
M-x compile
C-^
でエラー箇所へ飛ぶので楽だぞ。

506 名前:デフォルトの名無しさん :04/02/13 19:12
>>501-502
Win98のdosなので標準エラーへのリダイレクト・パイプは無理でした
>>500
ありがたう
>>503
試してみる

507 名前:デフォルトの名無しさん :04/02/13 19:30
>>503
プロパティを開いてみましたが、そんな項目はありませんでした
9x系のDOS窓では無理ですかね

508 名前:デフォルトの名無しさん :04/02/13 19:30
>>506
この期に Cygwin を入れてみれ。

509 名前:デフォルトの名無しさん :04/02/13 19:30
>>507
確か 9x 系にはバッファサイズの指定は無かったと思う。

510 名前:デフォルトの名無しさん :04/02/13 19:40
Windows98の dos なら、
command /c make > hoge ってな感じでもう一個 command.com 起動して
リダイレクトしてあげればエラー出力もファイルに書けたような記憶がある。。。


511 名前:デフォルトの名無しさん :04/02/13 20:32
MSYS!

512 名前:デフォルトの名無しさん :04/02/14 01:28
<cstdio>において、bcc5.5やmingwでは
stdoutやstdinがdefineされているのですが、
標準ではstdの名前空間内になくていいものなのですか?

513 名前:デフォルトの名無しさん :04/02/14 01:35
プリプロセッサマクロに名前空間など無い。

514 名前:デフォルトの名無しさん :04/02/14 01:37
そいういうことを言ってるんじゃないだろ...。

515 名前:デフォルトの名無しさん :04/02/14 01:38
>>514 じゃー何を?

516 名前:デフォルトの名無しさん :04/02/14 01:46
例えば GCC だと

 #define stdin ((__getreent())->_stdin)

になってるけど、これだと std::stdin と使うことができない。
これは C++ の仕様として正しいのか?
std::stdin と使えなくていいのか?
という質問でしょう。

517 名前:デフォルトの名無しさん :04/02/14 02:00
namespace std { inline FILE* _std_PFILE(FILE* val) { return val; } }
#define stdin _std_PFILE((__getreent())->_stdin)
とかにすればいいのにナ。

518 名前:デフォルトの名無しさん :04/02/14 02:03
もう一度言う、プリプロセッサマクロに名前空間など無い。

519 名前:デフォルトの名無しさん :04/02/14 02:07
……

520 名前:デフォルトの名無しさん :04/02/14 02:09
stdin が std 名前空間内の識別子、
もしくは、それに展開されるマクロでないのだが、
それは C++ の仕様から許されるのかって質問だろ?

521 名前:デフォルトの名無しさん :04/02/14 02:19
stdin/stdout/stderrは標準Cライブラリのマクロで、C++でも同じものが提供されている。
あとは、>>513

522 名前:デフォルトの名無しさん :04/02/14 02:41
>512です。
レスをくださったみなさん、
言葉足らずな質問で混乱させてしまい、
申し訳ありませんでした。
基本的には>516さんと>520さんの
おっしゃるとおりです。

>521さん
stdin/stdout/stderrはグローバル変数ではなく、
マクロとして定義されていたのですね。
これでなんかすっきりしました。
ありがとうございました。

523 名前:デフォルトの名無しさん :04/02/14 03:37
>>521
ホントだ。マクロって書いてあるな。

じゃ、g++ で printf が std:: なしで使えるのはどうなんだろう?
しかも、std:: なしだとフォーマットチェックの警告が出ないし...。

524 名前:デフォルトの名無しさん :04/02/14 04:24
>>523 ttp://gcc.gnu.org/bugzilla/show_bug.cgi?id=6257

525 名前:デフォルトの名無しさん :04/02/14 05:36
>>524
C 用のライブラリを使いにくいから...ってことか。
確かにそうだなぁ。

526 名前:デフォルトの名無しさん :04/02/14 17:06
すみません、C++で質問なんですが
2行3列の行列の和を求める関数 int sum(int x[][3],int y[][3],int z[][3])
で仮引数x[][3]をx[][]と出来ないのは何故ですか?

また、この関数だとn行3列の行列の和しか出せないのですが
n行m列の行列の和を出す関数は作れないんでしょうか?


527 名前:デフォルトの名無しさん :04/02/14 17:14
C統合・質問スレッド
http://pc2.2ch.net/test/read.cgi/tech/1068359871/56-57

528 名前:デフォルトの名無しさん :04/02/14 17:21
>>526
すでにCのスレが回答が出てるようだけど
C++というよりまるっきりCの質問だね。

529 名前:デフォルトの名無しさん :04/02/14 17:40
というか、マルチイクナイ

530 名前:デフォルトの名無しさん :04/02/14 17:45
>529
すみません;
初めC統合逝って書き込んでみたら一個前のレスが01/18だったもんで廃棄されたスレなのかと


531 名前:デフォルトの名無しさん :04/02/14 22:54
なるほど。

532 名前:デフォルトの名無しさん :04/02/14 23:26
>>530-531
だからと言って方々のスレにマルチする言い訳にはならん


533 名前:デフォルトの名無しさん :04/02/14 23:39
移行した旨を伝えるべきだな。
といっても、今回のは移行するのとほぼ同時にレスが返ってきてるので、
逆にこっちに回答がありましたというべきだったか。
でも、>>527 も意外と即レスだったので...うむぅ。

534 名前:デフォルトの名無しさん :04/02/15 03:26
_spawnl( _P_WAIT, "hoge.exe", "-AA temp.txt result.txt" );
プロセスを新しく起動させたくて上のコードを実行しましたが
例外が発生してしまいます。
パスに日本語がない状態で実行しても例外が発生します。

別に新規に上のソースだけバージョンを作って実行すると問題なく完了します。

タイプミスやファイルの有無も確認しましたが、
どうしてもエラーの原因がわかりません。
どなたかご存知ではないでしょうか?
VC++ 6.0 win98

535 名前:デフォルトの名無しさん :04/02/15 03:36
俺は_spawnl使ったことないけど、
↓こうじゃないの?

_spawnl( _P_WAIT, "hoge.exe", "-AA", "temp.txt", "result.txt", NULL );

これでも駄目ならグローバル変数 errno を参照するとか

536 名前:デフォルトの名無しさん :04/02/15 03:54
_spawnl( _P_WAIT, "hoge.exe", "-AA", "temp.txt", "result.txt" );
_spawnl( _P_WAIT, "C:\\a\\down3\\hoge.exe", "-AA temp.txt result.txt" );
_spawnl( _P_WAIT, "C:\\a\\down3\\Sjet.exe", "-AA", "temp.txt", "result.txt" );
フルパス指定してみましたが、これでも例外が発生しました。
かんじんの errno は 0 です。

これ以上手がかりないです・・・

537 名前:デフォルトの名無しさん :04/02/15 04:15
いや、重要なのは最後のNULLなんだけど・・・

538 名前:デフォルトの名無しさん :04/02/15 04:19
素直に CreateProcess 使いまつ
シングルイベントが良かったのだがおおおおおお
MSめぇ手ぇぬいたなぁあああああ

539 名前:デフォルトの名無しさん :04/02/15 04:22
すれ違い
NULL で、できました
どうもありがとうございました。

でも 今日は寝まーす

540 名前:デフォルトの名無しさん :04/02/15 05:36
シングルイベント?

541 名前:デフォルトの名無しさん :04/02/15 07:32
勝手に俺用語定義するな

542 名前:デフォルトの名無しさん :04/02/15 10:42
いや、定義はまだ見当たらないから、未解決参照にして読んだ。
よって今のところ意味不明。

543 名前:デフォルトの名無しさん :04/02/15 19:34
template <class T>
void test(T t){}

template <>
void test<int>(int t){}

みたいに特殊化する時、<int>があるのとないのとでは違いはあるのでしょうか。
あと >>341

template< class T1, class T2 >
void hoge( T1 & t1, T2 & t2 )
{ cout << t1.value << t2.value << endl; }

template< class T1 >
void hoge( foo<T1> & t1, T1 n )
{ cout << t1.value << n << endl; }

でもよくないですか?

544 名前:538 :04/02/15 20:37
眠かったんだよ
見逃してちょ
シングルスレッド

545 名前:デフォルトの名無しさん :04/02/15 20:58
>>544
#define シングルイベント シングルスレッド
了解。

ところで、普通マルチスレッドというと
1プロセスの中で複数のスレッドが走っている
ことを言うのだが?

546 名前:538 :04/02/15 21:07
>>545
そのようだが?

547 名前:538 :04/02/15 21:21
OKOK
やっと分かった
同期させたかった
これでいいかな?
main で処理した結果をテキストに出力して、
それを解析する別のexeファイルを起動させて、テキストに出力して、
main では、解析を待つ状態を作りたかったわけ

中途半端な使い方がいけなかったかもしれん
というわけで
#undef シングルスレッド

548 名前:デフォルトの名無しさん :04/02/15 21:25
_spawnl や CreateProcess はスレッドの数とは無関係なわけで、
>>538の発言は未だに意味がわからない。

549 名前:538 :04/02/15 21:34
俺の間違い
===終了===

550 名前:デフォルトの名無しさん :04/02/15 22:16
>>549
シングルイベント -> シングルスレッド
シングルスレッド -> #undef

OK?

551 名前:デフォルトの名無しさん :04/02/15 22:36
シャ乱Qかよ

552 名前:デフォルトの名無しさん :04/02/15 22:37
シングルスレッドで夢とお前を抱いてるのかよ!

553 名前:デフォルトの名無しさん :04/02/15 22:39
2ch::シングルスッドレ

554 名前:デフォルトの名無しさん :04/02/15 22:39
>>551
俺も思った(*^-^*)

555 名前:デフォルトの名無しさん :04/02/15 23:25
ワラタ

556 名前:543 :04/02/16 00:20
教えてください。おながいします。

557 名前:デフォルトの名無しさん :04/02/16 00:38
>>543
> みたいに特殊化する時、<int>があるのとないのとでは違いはあるのでしょうか。

ないですよ。

> あと >>341
> ・・・
> でもよくないですか?

ダメだったんですか?

558 名前:543 :04/02/16 00:53
>>547
ありがとございます。
クラスの場合は関数みたいに引数で推論、みたいなことができないので
<int>は必要。であってますよね。
template <> void test<int>(int t){} より、
void test(int t){} の方が優先順位が高い様なのですが
そこらへんのルールってどうなってるんでしょう

341のは、僕は 543でいいと思ったんですけど
意図していることと違うのかなあと思ったので。

559 名前:デフォルトの名無しさん :04/02/16 01:17
>>558
> クラスの場合は関数みたいに引数で推論、みたいなことができないので
> <int>は必要。であってますよね。

あってると思いますよ。

> template <> void test<int>(int t){} より、
> void test(int t){} の方が優先順位が高い様なのですが
> そこらへんのルールってどうなってるんでしょう

こちらに詳しい資料がありますので、どうぞ。→ttp://www.kuzbass.ru/docs/isocpp/over.html

> 341のは、僕は 543でいいと思ったんですけど
> 意図していることと違うのかなあと思ったので。

>>341にテスト用のコードが載っているので、それで試されてはいかがでしょう?
それ以上の意図は、本人に聞かないとわからないでしょうね。

560 名前:デフォルトの名無しさん :04/02/16 07:09
Effective C++を今更ながら読んでます。
class固有のnewのオーバーロードについての宣言が

class X {
public:
static void *operator new(size_t size);
...
};

という感じで必ずstaticなのは何か理由があるのでしょうか?

561 名前:デフォルトの名無しさん :04/02/16 07:35
staticじゃないとX からしか new X できないじゃん?

562 名前:デフォルトの名無しさん :04/02/16 13:15
static付けなくても勝手にstaticになるんじゃなかったっけ?

563 名前:デフォルトの名無しさん :04/02/16 17:37
初歩的な質問


inline bool operator==(const aaa& str)const{

}

この const ってなんですか?

564 名前:デフォルトの名無しさん :04/02/16 17:39
なぜわからないのに初歩的だと言い切れるのか?
とお決まりのツッコミ。

565 名前:デフォルトの名無しさん :04/02/16 17:41
なんでだろう。


566 名前:デフォルトの名無しさん :04/02/16 17:42
>>563
どのconstだ?

>>564
言語仕様に関することだからじゃないか?

567 名前:デフォルトの名無しさん :04/02/16 17:44
inline bool operator==(const aaa& str)const{
~~~~~~
です。

何がコンストなんですか?

568 名前:デフォルトの名無しさん :04/02/16 17:44
空白はいらないんだった


569 名前:デフォルトの名無しさん :04/02/16 17:46
ここで質問して回答を待つより
入門書を読んだり入門サイトをぐぐって調べたりする方が
ずっと早く疑問が解決すると思うんだけど

570 名前:デフォルトの名無しさん :04/02/16 17:48
調べ中...

571 名前:デフォルトの名無しさん :04/02/16 17:51
面倒だから教えてやる。
1番目のconstはstrの指すインスタンスに対して変更できない事を示す。
2番目のconstはthisの指すインスタンスに対して変更できない事を示す。

572 名前:デフォルトの名無しさん :04/02/16 17:52
>>567
二番目のconstだと推測して回答。
class Xのメンバ関数の宣言の後ろにconstをつけると、そのメンバ関数はconst X型の
オブジェクトに対して呼ぶことができる。
これによって状態更新演算と状態取得演算の違いを明示できる。
組み込み型のconstの挙動にあわせるのが普通の使い方だが、
クラスの設計者がconstの意味を定義できると考えてもよい。
mutableメンバも併せて調べるとよし。

573 名前:デフォルトの名無しさん :04/02/16 17:55
なるほど。
thisですか。

どうもありがとうございました。

574 名前:デフォルトの名無しさん :04/02/16 17:56
this is unco

575 名前:デフォルトの名無しさん :04/02/16 21:28
> クラスの設計者がconstの意味を定義できると考えてもよい。

よくないと思いますよ。


576 名前:デフォルトの名無しさん :04/02/16 22:07
>>574
is 演算子のある言語ならいけそうだな。

577 名前:デフォルトの名無しさん :04/02/16 22:35
const と mutable の関係。
const と const_cast の関係。

578 名前:デフォルトの名無しさん :04/02/16 22:38
volatile

579 名前:デフォルトの名無しさん :04/02/16 23:58
const volatileを組み合わせるとconstだけでもなく、volatile
だけでもない新しい属性が発生するというこの複雑さ。

お陰でメンバ関数をたーくさん書く羽目に。

580 名前:デフォルトの名無しさん :04/02/17 00:03
this is not manko
i am pen

581 名前:デフォルトの名無しさん :04/02/17 00:33
>>576
演算子の定義できる言語なら(以下略

582 名前:デフォルトの名無しさん :04/02/17 05:44
#define is ->

583 名前:デフォルトの名無しさん :04/02/17 12:38
いままでCしかやったことなくて
今C++を勉強しています。
講座を見ると
using namespace std;
と初めに書いてあるのですが
これは一体なんのために書いてあるのかわかりません。


584 名前:デフォルトの名無しさん :04/02/17 12:54
よほど古いものでない限り
どんな入門書にも
どんな入門サイトにも
書いてあります

585 名前:デフォルトの名無しさん :04/02/17 16:33
>>583
namespace std
{
//ココ
}
の中で定義された関数、クラス等をどこででも、つまり「std::vector<int> ...」
などとしなくても「vector<int> ...」のように使えるようにする操作。名前の
衝突が起こりやすくなるため、グローバル(この場合翻訳単位ということに
なるが)でこれを行うことは推奨しない。面倒臭くても出来る限り小さな
スコープの中で行うことが求められる。ただし、規模の小さなコード、
すなわち入門書の練習問題程度では問題にならないことが多い。
「名前空間(namespace)」について勉強することをお勧めする。

586 名前:デフォルトの名無しさん :04/02/17 16:55
名前空間は全部usingでグローバルに導入して、
衝突の起こったときだけ限定子で明示するってのも
ありのような気がするんだが、推奨されてないのは何か理由があるのかな。

587 名前:デフォルトの名無しさん :04/02/17 17:09
>>586
気持ち悪いYO!

宗教戦争の悪寒…

588 名前:デフォルトの名無しさん :04/02/17 17:11
やっぱ、「偶然の一致」じゃないかな。
typoで意図しないものが呼ばれてしまうとか。
(特に1引数コンストラクタやoperator系)

589 名前:デフォルトの名無しさん :04/02/17 17:24
>>588
なるほど。そこまで考えてなかったよ。

590 名前:583 :04/02/17 19:42
>>585
丁寧な説明ありがとうございます。

591 名前:デフォルトの名無しさん :04/02/17 20:21
deleteについて教えてくださいm(__)m
配列でnewしたオブジェクトのポインタは
delete [] p
で解放しないといけないとダメとのことですが
vc6.0でステップ実行したところ[]を付けても付けなくても
同じoparator::delete()が呼ばれていて、中身はcのfree()
をラップしただけなのですがどういうことなのでしょうか?

592 名前:デフォルトの名無しさん :04/02/17 20:33
>>586
もはやこれは宗教戦争だけど、漏れはstd名前空間だけならグローバルでもいいと思う

593 名前:デフォルトの名無しさん :04/02/17 20:38
>>591
ある環境で動くことが、他の環境でも動くことを保証するわけではない。

まぁ、大抵の場合はデストラクタがない型なら [ ] なくても動くとは思うが、
だからといって書かないってのはダメ。

要するに delete の場合は先頭のしかデストラクタが呼ばれず、
delete [ ] の場合は全てのオブジェクトでデストラクタが呼ばれる。
さらに、new [ ] の場合は(delete [ ] で使うための)オブジェクトの数を
保存する領域も同時に確保することが多く、
new [ ] で返される値と実際に確保されたメモリ領域の先頭アドレスとは
その分だけずれることが多い。

実際のところ、このあたりをどう実装するかは処理系依存で、
デバッグモードでのみデストラクタの有無に限らず delete と delete [ ] の処理が違ってても
何の文句も言えない。

594 名前:デフォルトの名無しさん :04/02/17 20:40
>>591
特定の処理系でうまく行った(ように見えた)としても
規格に合致しているわけではないからdelete[]を使うべき。
vc6での正確な挙動は忘れたが、ただのdeleteで配列全体の
デストラクタが呼ばれるか試してみると良い。

595 名前:591 :04/02/17 20:59
>>593-594
なるほど!処理系依存なんですね。
デストラクタが呼ばれるかは試してなかったのですが、MFCアプリで[]を
付けずにコンパイルしたらアサーションされたのに、[]を付けたら
走ったので、何が違うのかと思ってステップ実行したら同じoperator::delete
が呼ばれていたので何が違うんだろうと思ったのでした。
ありがとうございました。。。

596 名前:デフォルトの名無しさん :04/02/17 21:01
デストラクタを呼ぶ部分は
operator delete(...) の中には無いからね。
operator delete(...) を呼ぶ前に実行される。

597 名前:591 :04/02/17 21:03
>>596
あっ、そうか!その部分こそ処理系(実装)依存でソースを
追っていても見えないんですね。
よくわかりました。。。

598 名前:デフォルトの名無しさん :04/02/17 21:10
デストラクタを呼ぶのが
operator delete が呼ばれる前ってのは
処理系依存じゃないんだけど...。

599 名前:デフォルトの名無しさん :04/02/17 21:18
>>598
いやそのこと自体を処理系依存と言ってるわけじゃないだろう。

600 名前:591 :04/02/17 21:19
あ、大丈夫です
変な書き方してすみません(汗


601 名前:デフォルトの名無しさん :04/02/17 21:23
vector<string> で5000個ほどのデータを管理したいんですがそのまま使うとメモリを
食いすぎてエラーを起こしてしまいます。。
いろいろ調べて new すればいいことまではわかったのですが、肝心の vector<string>
での new の仕方が分かりませんでした。
初歩的な質問であることは重々承知しているのですが、どなたか分かる方がいれば
教えてくださいm(__)m

602 名前:デフォルトの名無しさん :04/02/17 21:23
More Exceptional C++オモシロイ。STLのきわどい使い方や
遅延評価など新しいトピックが満載。感想は「痒い所に手が
届く」といった感じだ。

603 名前:デフォルトの名無しさん :04/02/17 21:33
>>601 難しくないよね。

#include <iostream>
#include <vector>
#include <string>

typedef std::vector<std::string> Vs;

int main()
{
Vs* vsp;

vsp = new Vs(5000);

(*vsp)[4999] = "abcdef";

std::cout << (*vsp)[4999] << std::endl;

delete vsp;
}

604 名前:601 :04/02/17 21:37
なるほど・・・
さっそく試してみます。
603さんありがとう!ありがとう!

605 名前:デフォルトの名無しさん :04/02/17 21:38
ええと

606 名前:デフォルトの名無しさん :04/02/17 21:39
>>601
何も分かってないべ。
new することに意味は全く無い。

vector<string> でメモリが足らなければ、
少々のことしたくらいではメモリが足りるようにならない。
というか、そんくらいで一杯になるメモリって何?
他の何かがおかしいんじゃないの?

あと、再確保は嬉しくないので
できるなら最初に vector のサイズを指定した方がいい。

607 名前:デフォルトの名無しさん :04/02/17 21:41
>>604
後、参照外しが面倒ならこういう風にしてもいいべ。

#include <iostream>
#include <vector>
#include <string>

typedef std::vector<std::string> Vs;

int main()
{
Vs* vsp;
Vs vs;

vsp = new Vs(5000);
vs = *vsp;

vs[4999] = "abcdef";

std::cout << vs[4999] << std::endl;

delete vsp;
}

608 名前:デフォルトの名無しさん :04/02/17 21:47
>>606
実装次第だと思うけど、vectorの本体も、中身のstringも
ヒープ領域に確保されるという気がするよねえ。5000個とか
数はあまり関係ないような気がする。

609 名前:デフォルトの名無しさん :04/02/17 22:17
>>607
...。Vs& vs = *vsp; なら分かるが。

610 名前:デフォルトの名無しさん :04/02/17 22:25
>>609
&つけて参照しないと、新しいオブジェクトが作られるだけだね。
だから&無しではvs[4999]に何か代入しても(*vsp)[4999]は空のままだ。

611 名前:デフォルトの名無しさん :04/02/17 22:33
ポインタにする意味はないと思うんだけど…

612 名前:デフォルトの名無しさん :04/02/17 22:40
ないよ。全く。

613 名前:デフォルトの名無しさん :04/02/17 22:42
>>611
こうかい?段々プログラムがねじれて行く気がするんだけど・・・・

typedef std::vector<std::string> Vs;

int main()
{
Vs& vs = *(new Vs(5000));

vs[4999] = "abcdef";
vs.resize(10000);

std::cout << vs[4999] << std::endl;
std::cout << "size = " << vs.size() << std::endl;

delete &vs;
}

614 名前:デフォルトの名無しさん :04/02/17 22:51
new する意味が無いと言ってるというのに...。

615 名前:デフォルトの名無しさん :04/02/17 22:53
int main()
{
  std::vector<std::string> vs;

  vs.resize(5000);
  vs[4999] = "abcdef";

  std::cout << vs[4999] << std::endl;
}

で、いいだろ。
vectorの中身はヒープ領域に確保されるんだから。


616 名前:デフォルトの名無しさん :04/02/17 23:03
>>614>>615
やっぱそうだよな。それにしても>>601さんの書き込みが
気に掛かる。。。

617 名前:デフォルトの名無しさん :04/02/17 23:15
割り込みすみません。初心者質問ですがおせてください。
よく「VBはランタイムがいる」とか言いますが、cやc++も
ランタイムというかライブラリが要りますが、これは静的に
リンクされているために実行時には不要ということなのでしょうか?
標準ライブラリとかはものすごいデカイので静的にリンクすると
ものすごいデカイ実行ファイルになってしまうと思うのですが。


618 名前:デフォルトの名無しさん :04/02/17 23:20
>>617
LIBファイルの構造による。関数一つ一つをバラバラにしてある
LIBと、いくつかの関連する関数をまとめてパックしたLIBでは
リンクされる大きさが違う。

Cはそういう傾向があるが、C++は継承が多用されているので
ガバッとリンクされる。動的にリンクする事も大抵できるので
お試しあれ。

619 名前:617 :04/02/17 23:25
>>618
レスどうもありがとうございますm(__)m
なるほど、標準ライブラリといっても複数のLIBに分解されているので
#includeするヘッダによってリンクされるLIBが決まってくると
いうことなのですね。VBあがりの初心者VCプログラマなのですが
VCにはVBのようなランタイムがないのでわかりにくかったのですが
理解できました。

620 名前:デフォルトの名無しさん :04/02/17 23:30
>>619
違う。#includeで決まるわけではない。
「関数を実際に使わないと」リンクされない。

621 名前:デフォルトの名無しさん :04/02/17 23:31
という実装が多いだけだな。
呼び出されていない関数の未解決参照を
「エラーにしなくてよい」というだけの話。

622 名前:617 :04/02/17 23:34
>>620
あ、なるほど。
ところで、たとえば今ヘッダで
#include <vector>
と書いて、実際に
vector<int> vi;
と宣言して使用したとして、リンカはvectorの実装がどのLIBに
存在するかどうやって知るのですか?



623 名前:デフォルトの名無しさん :04/02/17 23:40
リンクするのは、.cをコンパイルした.objファィル。
LIBは.obj(.o)を集めたファィル。
その中から実際に使われる.objファィルだけがリンクされる

624 名前:デフォルトの名無しさん :04/02/17 23:44
>>622
基本的には暗黙なものを含めて指定されたオブジェクトファイルとライブラリを
全てリンクするだけ。完全に同名の関数が複数あればエラー吐いて終わり。
どこに実装があったかなんか知ったこっちゃない。

625 名前:617 :04/02/17 23:44
>>621さんもどうもです。
>>623
LIBファイルというのはobjファイルの集合だったんですね。
で、リンカは実装が存在するobjファイルを探して
それだけをリンクの対象にするということですか。
基本的なことがわかってなくてすみませんでした。
みなさんどうもありがとう...。

626 名前:デフォルトの名無しさん :04/02/17 23:46
>>622
vector は テンプレートライブラリだから
他に何もリンクしないと思う。
何か特殊化してるものがあったら分からんけど。

まぁ、そんなことはどうでも良くて、
標準ライブラリであればコンパイラやリンカの方で
自動的にチェックしてくれるのが殆どだと思う。
だから、そのあたりをいじるには、
リンカか何かのオプションをいじればいいと思う。

627 名前:デフォルトの名無しさん :04/02/17 23:46
ちなみにほとんどの実装でstd::vector<>の実装なんてものは存在しない。

628 名前:デフォルトの名無しさん :04/02/17 23:49
>>627
ヘッダに入っちゃってるからってこと!?

629 名前:デフォルトの名無しさん :04/02/18 00:24
STLつかうと一気に実行ファイルサイズが10倍に?!


630 名前:デフォルトの名無しさん :04/02/18 00:31
>>629
おまいのコードはせいぜいレス番程度のライン数

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

632 名前:デフォルトの名無しさん :04/02/18 00:38
>>631
>>28

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

634 名前:デフォルトの名無しさん :04/02/18 00:47
>>633
#include "stdafx.h"

後死ね。

635 名前:デフォルトの名無しさん :04/02/18 00:49
【初心者歓迎】C/C++室 Ver.4【環境依存OK】
http://pc2.2ch.net/test/read.cgi/tech/1073473867/

636 名前:デフォルトの名無しさん :04/02/18 00:57
>>601
> vector<string> で5000個ほどのデータを管理したいんですがそのまま使うとメモリを
> 食いすぎてエラーを起こしてしまいます。。

たぶんこれが、メモリの食いすぎじゃないんだろうな。

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

638 名前:デフォルトの名無しさん :04/02/18 01:31
おまえら、いい加減にそのネタから離れろ

639 名前:デフォルトの名無しさん :04/02/18 02:05
容疑者を絞り込むために、小さいテストプログラムを作る事をお勧めする。

int main()
{
 const size_t max_size = 5000;
 vector<string> arr(max_size);
 char buffer1[256];
 size_t i=0;
 for(i=0; i<max_size; i++){
  sprintf(buffer1, "私は、%04dです。", i);
  arr[i] = buffer1;
 }
 
 for(i=0; i<max_size; i++){
  cout << arr[i] << endl;
 }
 
 return 0;
}

ま、結論から言うと、vector<string>に罪はないってこった。

640 名前:デフォルトの名無しさん :04/02/18 05:38
n個の整数型定数a[n]が与えられているとき
n個の整数型変数x[n]の値を次のように定める。

数学的な意味での集合として { x[0] , x[1] … x[n-1] }={ a[0] , a[1] … a[n-1] }
任意のi,j(i≠j)に対して x[i]≠x[j]

つまりn個の定数の順列を考えているわけです。
ですから当然n!=n*(n-1) … 2*1個のパターンがあるわけなんですが
これを具体的に設定する上手い方法を思いつきません。

例えばn=3くらいであれば
for(int i=0; i<3; i++){
for(int j=0; i<3; j++){
for(int k=0; k<3; k++){
x[0]=a[i],x[1]=a[j],x[2]=a[k];
if(x[0]!=x[1] && x[1]!=x[2] && x[2]!=x[0]){
cout<<x[0]<<endl<<x[1]<<endl<<x[2]; } } } }

などとすれば一応出来るのですが、一般の個数nの場合ですと
このような方法ではいたずらにソースコードが増えてしまいます。

何か良い方法はないでしょうか。
よろしくお願いします。

641 名前:デフォルトの名無しさん :04/02/18 05:44
>>640
再帰は?

642 名前:デフォルトの名無しさん :04/02/18 05:55
>>640
ここはstd::next_permutationに限るな

643 名前:デフォルトの名無しさん :04/02/18 09:43

#include <stdio.h>

char s[4]={'A','B','C','D'};

void fun(int i)
{
 char c;
 int j,k;
 for(k=i;k>0;k--){
  for(j=i-1;j>0;j--){
  printf("%s\n",s);
  c=s[j];
  s[j]=s[j-1];
  s[j-1]=c;
  }
 }
}

int main ()
{
 fun (4);
 return 0;
}

C++だとどうなるんだろ。

644 名前:デフォルトの名無しさん :04/02/18 10:14
>>642
同意
標準ライブラリに、こんなときに使わなくてどうするって関数があるんだもんな。

645 名前:デフォルトの名無しさん :04/02/18 13:40
#include <iostream>
class CSub;
class CBase {
public:
 CBase(){}
 ~CBase(){}
 CSub* CreateSub() { CSub *node = new CSub; return node; }
};
class CSub {
public:
 CSub(){}
 ~CSub(){}
};

int main(){ return 0; }

初歩的ですいません。
上のコードをコンパイルすると
error C2512: 'CSub' : クラス、構造体、共用体にデフォルト コンストラクタがありません。
と でてコンパイルできません。
コンストラクタもデストラクタも定義しているはずなのですが、
どこがいけないのでしょうか?
VC++6.0

646 名前:デフォルトの名無しさん :04/02/18 13:56
>>645
僕も初心者で申し訳ないのですが
class CSubの定義を前方宣言の位置に書くと通りますね。
なんでだろう。。。

647 名前:デフォルトの名無しさん :04/02/18 13:57
>>645
空宣言が有効なのはポインタと引数だけ。
インライン関数はダメ。

CreateSubをインライン関数にせずに、CSubの宣言の後で定義すれば大丈夫なはず

648 名前:デフォルトの名無しさん :04/02/18 14:00
>>647
厳密に言えば空宣言を使ってインスタンスを生成するのは違反ってことだな

649 名前:645 :04/02/18 14:10
>>647,648
YEAH!
前方宣言だったぜ
最近イージーミスが多い いかんいかん

650 名前:デフォルトの名無しさん :04/02/18 14:15
>>649
645とえらいキャラが違うなw

651 名前:645 :04/02/18 14:23
すいません ギャップが激しいもので
あ、単細胞とか言わないで下さいね。

652 名前:デフォルトの名無しさん :04/02/18 14:23
質問おながいします。
基底クラスでデストラクタをvirtualで宣言したとき
派生オブジェクトをdeleteすると、派生・基底ともに
デストラクタが呼ばれますが、virtualの本来の性質から
いうと派生クラスのデストラクタのみ走るべきでは
ないのですか?これはc++の仕様なのでしょうか?

653 名前:デフォルトの名無しさん :04/02/18 14:25
仕様です。
virtual じゃなくてもそうなります。
「デストラクタ」の本来の性質が優先されているわけです。

654 名前:デフォルトの名無しさん :04/02/18 14:27
というか派生しか走らなかったら、抽象クラスならまだしも
基底クラスの要素を削除するやつがいなくなるからな。

それじゃ困るだろ?

655 名前:652 :04/02/18 14:29
>>653
レスどうもです。
>「デストラクタ」の本来の性質が優先されているわけです。
とすると、よく基底クラスのデストラクタはvirtualとして
宣言しておかないと
CBase *pb=new CDerived();
delete pb;
としたとき派生クラスのデストラクタのみ走って基底クラスのが
走らないミスが言われますが、なぜvirtualでなくとも基底クラス
のデストラクタが走る設計にc++はなってないのでしょうか?

656 名前:652 :04/02/18 14:32
すみません。
×派生クラスのデストラクタのみ走って基底クラスのが走らない
○基底クラスのデストラクタのみ走って派生クラスのが走らない
でした。

657 名前:652 :04/02/18 14:34
度々すみません。やっぱり
×基底クラスのデストラクタのみ走って派生クラスのが走らない
○派生クラスのデストラクタのみ走って基底クラスのが走らない
でした。


658 名前:デフォルトの名無しさん :04/02/18 14:36
>>655
効率のため

659 名前:652 :04/02/18 14:37
スレ汚くしてスミマセン。
ちょっと頭冷やしてきます。

660 名前:デフォルトの名無しさん :04/02/18 14:54
>654
任意に呼び出す事もできるけどな。

設計が悪いのは解っているが、
たまに派生要素の削除の前に基底のデストラクタを呼びたいとき、
派生のデストラクタの先頭で呼び出すことがある。
その後もう一回呼ばれてしまうのが気持ち悪いが。

661 名前:デフォルトの名無しさん :04/02/18 15:31
気持ち悪いと言う程度の問題なのか…

662 名前:デフォルトの名無しさん :04/02/18 15:55
>>655
多分、「なぜデストラクタにはvirtualが必要」ではなく、
「なぜコンストラクタにはvirtualが必要じゃない」が正しい疑問なんだと思う。
理由は、呼び出されるべきコンストラクタのアドレスは全て静的に決定できるのに対し
デストラクタは実行時じゃないとわからないからだと思う。

D* d = NULL;
switch( x )
{
case 0: d = new A;
case 1: d = new B;
case 2: d = new C;
}
delete d;

663 名前:デフォルトの名無しさん :04/02/18 15:58
C++標準がどう考えてるかはARMでも読めばいいとして、
単純な話デストラクタを強制的にvirtual扱いすると、仮想関数が一つもないクラスでもvptrとvtblがくっついちゃって
効率に影響を及ぼすっていう理由があるんじゃないでしょうか。

664 名前:デフォルトの名無しさん :04/02/18 17:19
>>663
complex とかがいい例だね。

665 名前:デフォルトの名無しさん :04/02/18 20:13
perlのcrypt関数と同じ動作をC++でもさせたいのですが、
unistd.hが無いのでその関数が使えません。
どうにかしてC++でcrypt関数を使う事は出来ないでしょうか?

666 名前:デフォルトの名無しさん :04/02/18 20:15
元スレから見てるけど
君の移動すべきスレはこっちだよ
http://pc2.2ch.net/test/read.cgi/tech/1077102238/

667 名前:デフォルトの名無しさん :04/02/18 20:15
http://human2.2ch.net/test/read.cgi/owarai/1077005953/

668 名前:665 :04/02/18 20:21
移動します。

669 名前:デフォルトの名無しさん :04/02/19 01:26
お願いします。
VC++6.0なのですが、newに失敗してもbad_alloc例外がスローされずに
ヌルポインタが返ってくるのですが、これはコンパイラの仕様なの
でしょうか?
本を読んだら#include <new>すれば比較的新しい処理系(コンパイラ)
は例外を投げると書いてあったのですが。

670 名前:デフォルトの名無しさん :04/02/19 01:35
>>669
VC++6.0はその点では「古い処理系」に当たる。

671 名前:デフォルトの名無しさん :04/02/19 01:37
その他の点も含めて「古い処理系」だな。

672 名前:デフォルトの名無しさん :04/02/19 01:39
>>671
そうだな。確かメンバテンプレートが使えないので
STLのコンテナは軒並みデフォルトのアロケータが
使えなかったような記憶が。

673 名前:デフォルトの名無しさん :04/02/19 01:59
宣言部(でいいんだっけ?)で実装すれば
一応メンバテンプレートも書ける。

674 名前:デフォルトの名無しさん :04/02/19 02:04
VC++6.0付属のヘッダとかには一応bad_allocの定義とかあるし、
CRTのソースにはなんかあるような気配なんで、どっちかつーと過去互換の
問題っぽいけどな。
一応bad_alloc投げさせたい場合は_set_new_handler()ってことになってるが。

675 名前:デフォルトの名無しさん :04/02/19 02:34
Dinkumware の ver3.08 にはVC++6.0でも動く
std::set_new_handler があってちゃんと動作する。

676 名前:デフォルトの名無しさん :04/02/19 05:38
概念的な話になって申し訳ありませんが、
privateな仮想関数ってどういう風に使うんですか?
クライアントコードからは多様的に使えないわけで、
既定クラス・派生クラス間で単に同じ名前の関数がある
(両者になにか関連があるというわけではない)というだけ
になるんでしょうか。



677 名前:デフォルトの名無しさん :04/02/19 06:53
template method。

678 名前:デフォルトの名無しさん :04/02/19 06:53
>>676

普通は使わない方がいいとされてる。
派生クラスでprivate関数の振る舞いを変えるのは基底クラスの意図しないところであるから。

679 名前:676 :04/02/19 07:37
template methodはprotectedの方がよくないですか?

680 名前:デフォルトの名無しさん :04/02/19 07:55
それ以前に、private・protected・publicは、
派生クラスでの属性変更が可能では?

protected→public
public→protected

というか、コンパイル時しか関係ないような事に
神経つかうのは時間の無駄ですよ、きっと。
私、経験ありますから(w

681 名前:デフォルトの名無しさん :04/02/19 08:11
private な仮想関数は多分使ったことないな。
オーバーライドするときに、
基底クラスの仮想関数を派生クラスで呼ぶことを禁止する、
ってな状況であれば使うこともあるかもしれんが。

>>680
>というか、コンパイル時しか関係ないような事に
>神経つかうのは時間の無駄ですよ、きっと。
には全面的には同意しかねるが、
今回のことに関してはそうかもな。

682 名前:デフォルトの名無しさん :04/02/19 08:12
template methodとしてしか呼び出されたくないが純粋仮想関数ではなく
デフォルトの実装を提供したければprivateじゃないとダメじゃないか?

683 名前:デフォルトの名無しさん :04/02/19 08:39
そのデフォルトの動作を派生クラスで使いたい場合は
protected にする必要があるけどね。

684 名前:デフォルトの名無しさん :04/02/19 08:56
http://cpptips.hyperformix.com/cpptips/priv_virt4

685 名前:デフォルトの名無しさん :04/02/19 13:34
class I_vfTCB
{
friend class vfTCB_Manager;

public:
I_vfTCB(void) : next(0),prev(0),Order(0) {}
virtual ~I_vfTCB() = 0 {}
private:
virtual void Run(void) = 0;
virtual void Remove(void) {}
I_vfTCB *next;
I_vfTCB *prev;
unsigned long Order;
};
こんなので使ってました。

686 名前:ahoneko :04/02/19 13:46
#include <iostream>
#include <string>
using namespace std;

class Neko{
string name;

public:
Neko(){}
Neko( string n ){
name = n;
}
void ShowName() const{
cout << "I'm " << name << "." << endl;
}
};

void GenerateNeko( Neko *neko ){
neko = new Neko( "TAMA" );
}

int main(){
Neko *x;
GenerateNeko( x );
x->ShowName();
}
どうしてこんなコードは、駄目なのにゃ〜。
ブルーバックスの「これならわかるC++」読んだけどわかりにゃせん。

687 名前:ヽ(´ー`)ノ :04/02/19 14:03
GenerateNeko() がおかしい。
main() の x と、GenerateNeko() の neko とじゃ刺してる先が違うぞ。

やるんなら、

Neko* GenerateNeko() {
return new Neko("TAMA");
}

x = GenerateNeko();

か、

void GenerateNeko(Neko** neko_ptr) {
*neko_ptr = new Neko("TAMA");
}

GenerateNeko(&x);

ポインタについて勉強しる。

688 名前:デフォルトの名無しさん :04/02/19 14:04
GenerateNekoのインスタンスをだれが破棄するんだ?

689 名前:ahoneko :04/02/19 14:16
687さん、ありがとうです。うまくいきましたわい。
ボインダについて勉強しましる。

690 名前:デフォルトの名無しさん :04/02/19 16:14
ぼいん、ぼい〜ん〜

691 名前:デフォルトの名無しさん :04/02/19 16:47
>>687
std::auto_ptr
boost::scoped_ptr

692 名前:ヽ(´ー`)ノ :04/02/19 16:57
言われなくたって分かってるよ(ノД`)俺じゃなくて質問者に言えよ


693 名前:デフォルトの名無しさん :04/02/19 18:39
>>689
これでもいいよ。ポインタのリファレンス。

void GenerateNeko(Neko*& neko)
{
neko = new Neko("TAMA");
}
int main()
{
Neko* x;
GenerateNeko(x);
x->ShowName();
}

694 名前:デフォルトの名無しさん :04/02/19 18:54
Newって遅いのか?
mallocを使うべきなのか!?
教えてください

695 名前:デフォルトの名無しさん :04/02/19 18:55
>>694
newもmallocも遅い。

696 名前:デフォルトの名無しさん :04/02/19 18:57
>>695
多用してはいけないと…

697 名前:デフォルトの名無しさん :04/02/19 19:01
メモリ管理は自分で書きなさい!

698 名前:デフォルトの名無しさん :04/02/19 19:02
ポインタって何よ?

なんで必要なの?

699 名前:デフォルトの名無しさん :04/02/19 19:04
いらない。窓から投げ捨てろ

700 名前:デフォルトの名無しさん :04/02/19 19:04
C++ではできるだけnewを使う方がよい(コンストラクタの呼び出し
をしてくれる)。内部的にはnewはmalloc()を呼び出しているよう
だけどね。

701 名前:デフォルトの名無しさん :04/02/19 19:04
ポインタがないと Hello, world! も書けない。

702 名前:デフォルトの名無しさん :04/02/19 19:05
ポインタなんてなくても
次のアドレス指定するコード書けばいいんじゃないの?
そうでもないの?

703 名前:デフォルトの名無しさん :04/02/19 19:08
>>701
putchar 使えば書けないことも無いけどな。

704 名前:デフォルトの名無しさん :04/02/19 19:17
C++ だと参照で事足りることも多いから、
C の頃よりはポインタを使う機会は少ないけど、
それでも結構使うな。

特に配列を受け渡すのやメモリの動的確保は参照だと不便だし、
ポインタだと NULL かそうでないかで処理を変えることができるのが便利。
あと、アドレスを途中で変更する必要があれば
ポインタを使わざるを得ない。

705 名前:デフォルトの名無しさん :04/02/19 19:30
>>704
C++ではNULLでなくて0ね。念のため。

706 名前:デフォルトの名無しさん :04/02/19 19:34
>>705
C でも 0 が使えるが...。

C++ だと #define NULL 0 なんで、
NULL も 0 も同じことだ。

707 名前:デフォルトの名無しさん :04/02/19 20:56
mainの関数へのポインタが使われてるし。

708 名前:デフォルトの名無しさん :04/02/19 21:30
>>707
const_castみたいなもんだな

709 名前:デフォルトの名無しさん :04/02/20 02:28
つーか多態使うのにポインタ使わんとどうしようもないだろ。


710 名前:デフォルトの名無しさん :04/02/20 02:40
参照で事足りる事も多いけどね。

711 名前:デフォルトの名無しさん :04/02/20 02:57
ポインタ乱用されたソースは、
かえって素人っぽいソースに見える罠。

712 名前:デフォルトの名無しさん :04/02/20 07:17
そこでSmart_pointer

713 名前:デフォルトの名無しさん :04/02/20 09:01
>>712
DLLでexportできねー。いや、C++前提ならともかく・・・。

714 名前:デフォルトの名無しさん :04/02/20 12:38
そんなあなたに COM


715 名前:デフォルトの名無しさん :04/02/20 17:12
stringクラスについてなんですが、

i = 10という結果が得られ、そこから hoge010 という文字列を作るときに

現在では

string piyo = "hoge"
char buf[10];
sprintf(buf, "%03d", i);
piyo += buf;

というようにstringクラスとcharを使い分けてます。

これをcharを使わないで実現する方法はないのですか?

716 名前:デフォルトの名無しさん :04/02/20 17:23
>>715
std::stringbuf

boost::format

717 名前:デフォルトの名無しさん :04/02/20 17:29
std::ostringstream out;
out << hoge;
out.width(3);
out.fill('0');
out << i;
std::cout << out.str();

718 名前:デフォルトの名無しさん :04/02/20 17:41
>716-717
ありがとうございます

719 名前:デフォルトの名無しさん :04/02/20 21:54
class a{
private:
int** ary;
public:
int& operator [][](int n1,int n2) {
return ary[n1][n2];
}
};
のような事がしたいんですが、エラーになります。
添え字演算子を2つオーバーロードして、2次元配列のような物を作る方法はないでしょうか?

720 名前:デフォルトの名無しさん :04/02/20 21:59
class a1 {
private:
 int* array;
public:
 int& operator[](int n) { return array[n]; }
 …
};

class a2 {
private:
 a1* array;
public:
 a1& operator[](int n) { return array[n]; }
 …
};


721 名前:デフォルトの名無しさん :04/02/20 22:03
もしくは

class a {
private:
 int** ary;
public:
 int* operator[](int n1) {
  return ary[n1];
 }
};

で妥協するか。

722 名前:719 :04/02/20 22:20
>>720-721
なるほど・・・
どうもありがとうございました。

723 名前:Addicted to C++ ◆cpp/Sz/v02 :04/02/21 14:46
http://pc2.2ch.net/test/read.cgi/tech/1075217631/743
こんなコードを書いたんですが、規格違反だそうです。
(http://pc2.2ch.net/test/read.cgi/tech/1075217631/744 さんの指摘)
#include <vector>以外に規格違反のところと、論拠となる規格書の
項目を教えてもらえると幸いです。結構検索かけてみたのですが
ピンと来ませんでした。お願いします。m(_ _)m

724 名前:デフォルトの名無しさん :04/02/21 15:23
変数の範囲に関する質問なんですが
ある環境でint型が-32767〜32767までの表示を持つとします。
このとき例えば400*100という計算をさせると結果はおかしくなるわけですが
複雑な計算を行っている状況において、どの段階で値の上限をオーバー
してしまったかを判定する方法はないでしょうか?

具体例として次のようなソースは文法的には間違いではないわけですが
aの値によっては計算結果に意味がなくなってしまいます。
こういう状況があるときに、最終段階になって結果がおかしいということではなく、
値の上限を超えた段階でエラーを拾いたいわけです。

int a;
cin>>a;
int b=400*a;

みなさんよろしくお願いします。


725 名前:デフォルトの名無しさん :04/02/21 15:54
>>724
C++ でオーバーフロー検出って出来たっけな。

C# 使え。
checked ってキーワード使えばオーバーフロー時に例外投げてもらえるから。

726 名前:724 :04/02/21 16:10
そうですか、C++ではこのようなことは出来ないんですね・・・

どうもありがとうございました

727 名前:デフォルトの名無しさん :04/02/21 16:17
>>723
14.3.1(Template type arguments)の2

728 名前:デフォルトの名無しさん :04/02/21 16:24
>>724
自分でチェックつきクラスを書くしかない。たとえば、
#include <limits>
#include <stdexcept>
#include <cstdlib>
#include <iostream>
template <typename Base> struct Checked
{
    Checked(Base b) : base(b) {}
    template <typename OtherBase>
    Checked operator*(const Checked<OtherBase> &other)
    {
        using namespace std;// absが組み込み型に対しても動作するように
        if(other.base == 0)
                return Checked(0);
        if(std::numeric_limits<Base>::max() / abs(base) > abs(other.base))
                throw std::overflow_error("nullpo");
        return Checked(base * other.base);
    }
private:
    Base base;
};
int main() try
{
    int a;
    std::cin >> a;
    Checked<int> ca(a);
    Checked<int> b = ca * Checked<int>(200);
}catch(std::exception &e)
{
    std::cout << e.what() << '\n';
}

729 名前:728 :04/02/21 16:33
>if(std::numeric_limits<Base>::max() / abs(base) > abs(other.base))
不等号が逆ですた。正しくは、
if(std::numeric_limits<Base>::max() / abs(base) < abs(other.base))

730 名前:デフォルトの名無しさん :04/02/21 17:28
移植性捨てていいならインラインアセンブラ使うのが簡単。

731 名前:デフォルトの名無しさん :04/02/21 17:56
キャリーか

732 名前:デフォルトの名無しさん :04/02/21 19:52
>>724
俺なら飽和演算があれば迷わず使う。移植性がどうたらと言うならインターフェースを作って。
なければ危険な演算を始める前に、オーバーフロー予測させるだろうな。
a を何倍までしていいのか? のように。

733 名前:デフォルトの名無しさん :04/02/21 20:01
>>732
飽和演算だと結果が変わるからこの場合不適当だろ。

734 名前:デフォルトの名無しさん :04/02/21 20:39
>>728
そこまでする必要あるの?

735 名前:デフォルトの名無しさん :04/02/21 21:14
>>733
724がエラーを拾ってどうするつもりか考えたわけだが、
其処もとの指摘どおりか否かはあいつの返答しだいだな。

736 名前:デフォルトの名無しさん :04/02/21 21:29
其処もと・・・

737 名前:Addicted to C++ ◆cpp/Sz/v02 :04/02/22 00:02
>>727
thx

738 名前:デフォルトの名無しさん :04/02/22 09:03
#include <iostream>
#include <vector>
using namespace std;

void sub( int *i )
{
 i += 100;
}
int main()
{
 vector<int> m;
 for( int i=0; i<10; i++ )
  m.push_back(i);

 vector<int>::iterator p = m.begin();
 while(p != m.end())
  {
   sub(p);
   cout << *p << " ";
   p++;
  }

 cout << endl;

 return 0;
}

739 名前:738 :04/02/22 09:03
実行結果
0 1 2 3 4 5 6 7 8 9

関数sub内で、イテレータを用いて 変数を書き換えるのですが、
関数subを出ると、変数がもとの値になっています。
これって iterator の使い方間違っているのでしょうか?
コンパイラは VC++6 です。

740 名前:デフォルトの名無しさん :04/02/22 09:08
>>739
*i += 100;

741 名前:デフォルトの名無しさん :04/02/22 09:10
>>739

#include <iostream>
#include <vector>

void sub(std::vector<int>::iterator& i)
{
*i += 100;
}

int main()
{
std::vector<int> m;
for (int i = 0; i < 10; i++)
m.push_back(i);

std::vector<int>::iterator p = m.begin();
while(p != m.end()) {
sub(p);
std::cout << *p << " ";
p++;
}

std::cout << std::endl;
}

742 名前:738 :04/02/22 09:16
イテレータについて勘違いしていました。
どうもでした。

743 名前:738 :04/02/22 09:22
>>741
VC++6.0 だと 上のソースの void sub(int *i);
でコンパイルが通るのですが、.NET だとコンパイルが通らないそうなのです。
(.NET 所持者いわく)

やはり void sub(int *i); は文法的に間違っているのでしょうか?
間違ってはいないが、void sub( std::vector<int>::iterator &i );
の方がベターなのでしょうか?
連続質問ですいません。

744 名前:デフォルトの名無しさん :04/02/22 10:05
>>743
1. 間違ってない。.NETは知らんが独自ルールがあるんではないの?
2. ベターということもない。汎用性が失われるので微妙。

745 名前:デフォルトの名無しさん :04/02/22 10:38
以下のようなソースコードで、

void hoge(void)
{
  int In_hoge;

  {
    int In_hoge_at_scope;
  }
}

変数In_hoge_at_scopeがスタックに確保されるのはいつですか?

関数hogeが呼ばれた時点で確保されるんですか、
それとも、スコープに入った時点ですか。

746 名前:デフォルトの名無しさん :04/02/22 10:41
>>745
> 変数In_hoge_at_scopeがスタックに確保されるのはいつですか?
一般論としては何も決まってない。そもそも、自動変数をスタックに確保する
とも決まってないし。

747 名前:デフォルトの名無しさん :04/02/22 10:43
>>745
その識別子を使ったアクセスができるのはスコープの中だけということしか言えない。
その外における挙動は未定義。

748 名前:745 :04/02/22 10:46
>>746-747

ありがとうございます。

749 名前:デフォルトの名無しさん :04/02/22 10:48
>>743
void sub(int *i);
この部分自体は間違ってない。けど、

std::vector<int>::iterator と int* は本来は違うものなので、
std::vector<int>::iterator を受け取るつもりで int* を使うのは間違い。
int* を受け取るつもりで std::vector<int>::iterator を使うのも間違い。
たまたまVC6だと両者が同じ型なんでうまくいっているだけ。

俺ならこうするか、
 void sub(std::vector<int>::iterator i)
  { *i += 100; }
こうする。
 void sub(int& i)
  { i += 100; }
 std::vector<int>::iterator p = m.begin();
 while(p != m.end()) {
  sub(*p);
  ++p;
 }
か、std::for_eachを使うけど勉強中ならまだfor_eachは気にせんでいい。

750 名前:デフォルトの名無しさん :04/02/22 10:49
>>743
iterator を受ける関数を作るときは、テンプレートにしておくと楽だ。
ポインタでも iterator でも動くしな。

>>744
vector の iterator はポインタの typedef とは限らないぞ。

vector の実装として、今の規格では
連続領域を取っているという保障もないんだっけかな?
でも、この規格は問題視されてて、
連続領域であることを規格で保障すべきだという意見が出てるんだっけ?
で、実際連続領域にしてない実装はないんだっけ?
と、うろ覚えで話す無責任さ。
詳しい人、間違いがあったら指摘してホスィ。


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