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


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

C++相談室 part51
251 名前:デフォルトの名無しさん :2006/07/22(土) 22:26:53
>>247
とんでもない嘘つくなよw

>>250
cmd.exeにargv[1]のファイルをD&Dして実行してみろ

252 名前:デフォルトの名無しさん :2006/07/22(土) 22:33:56
>>251
C:\〜〜>"プログラム本体" "目的のdat"
やってみてもファイルオープンで躓く
fstreamに必要な設定とかあるの?

253 名前:デフォルトの名無しさん :2006/07/22(土) 22:35:42
コマンドラインでなく直接パスを入れてみたら開くの?
ifstream inf("C:\Program Files\JaneDoeView\Logs\Logs\2ch\PC等\プログラム\1048668198.dat");

254 名前:デフォルトの名無しさん :2006/07/22(土) 22:37:02
どうせpermission deniedだろアホ

255 名前:デフォルトの名無しさん :2006/07/22(土) 22:38:22
どうせ下らんオチなんだろ

256 名前:デフォルトの名無しさん :2006/07/22(土) 22:38:54
かぶったw

257 名前:デフォルトの名無しさん :2006/07/22(土) 22:39:37
>>253
\\

258 名前:デフォルトの名無しさん :2006/07/22(土) 22:44:44
>>253
ifstream inf("C:\\Program Files\\JaneDoeView\\Logs\\Logs\\2ch\\PC等\\プログラム\\1048668198.dat");
としてやってみてもNo such file or directoryで駄目だった

259 名前:デフォルトの名無しさん :2006/07/22(土) 22:48:32
C:\abc def\ghi jkl\mno pqr.txt
とかいうファイルを作って開いてみようとは思わんのか

260 名前:デフォルトの名無しさん :2006/07/22(土) 22:50:07
notepad.exe C:\Prog〜 してみたら?

261 名前:デフォルトの名無しさん :2006/07/22(土) 22:51:17
ところでコンパイラは何使ってるの?実は日本語がうまく通らないコンパイラだったり・・

262 名前:デフォルトの名無しさん :2006/07/22(土) 23:00:31
>>260
メモ帳では開いた

>>261
タダで配布されてたVisualC++2005Expressつかってる

>>259
何故か思いつきもしなかった
"C:\\a s\\a s t\\a a.txt"でやってみたところどうしたわけか開いた
よく分からなかったんでレスつけられなかったけど>>254辺りが怪しいかもしれない

あまり長居すると悪いんであとは自分で調べてみる
ありがとう

263 名前:デフォルトの名無しさん :2006/07/22(土) 23:03:42
JaneDoe起動しながらプログラム実行していたと仮定して。
JaneDoeにファイルへの排他的アクセス権を奪われているとか。

264 名前:デフォルトの名無しさん :2006/07/22(土) 23:13:49
>>262
http://forums.microsoft.com/MSDN-JA/ShowPost.aspx?PostID=243152&SiteID=7
これだな。

265 名前:デフォルトの名無しさん :2006/07/22(土) 23:55:10
/dev/null や /dev/zero を表現したストリームって
用意されていないのでしょうか?

266 名前:デフォルトの名無しさん :2006/07/23(日) 00:01:12
>>265
/dev/null はあるんでない nul

267 名前:デフォルトの名無しさん :2006/07/23(日) 00:03:45
>>265
標準には無いね。 fstream で代用すれば?

268 名前:デフォルトの名無しさん :2006/07/23(日) 00:09:19
/dev/nullpo ならあるよ。

269 名前:デフォルトの名無しさん :2006/07/23(日) 00:15:05
/dev/ga お約束ですな

270 名前:デフォルトの名無しさん :2006/07/23(日) 00:30:32
char *p = 〜
unsigned char *p = static_cast< unsigned char* >( c );
がエラーになるんですけど何ででしょうか?
VS.net2003です。

271 名前:269 :2006/07/23(日) 00:31:23
間違えました
char *p
じゃなくて
char *c
です

272 名前:デフォルトの名無しさん :2006/07/23(日) 00:32:15
>>270
cがどこから来たか意味不明とか。
char*pとunsigned char*pで変数名の重複とか。
エラーメッセージ位かけよボケとか。
総じて意味不明

273 名前:デフォルトの名無しさん :2006/07/23(日) 00:35:15
>>270
char*からunsigned char*への暗黙の型変換ができないから。

274 名前:デフォルトの名無しさん :2006/07/23(日) 00:35:30
>>270
なんでエラーにならないと思うの?

275 名前:デフォルトの名無しさん :2006/07/23(日) 00:37:07
>>270
ちゃんとエラーの内容を書こうよ。答えがそのまま出てるから(笑

>test2.cpp(15) : error C2440: 'static_cast' : 'char *' から 'unsigned char *' に
>変換できません。
>        指示された型は関連がありません。変換には reinterpret_cast、C スタイル キ
>ャストまたは関数スタイルのキャストが必要です。

276 名前:デフォルトの名無しさん :2006/07/23(日) 00:37:59
void hoge() throw()
{
foo(); // 例外を投げるかもしれない関数
}

もしfoo()が例外を投げた場合の挙動は、どのように規定されているのでしょうか?

277 名前:デフォルトの名無しさん :2006/07/23(日) 00:47:47
>>276
std::unexpected() が実行され、デフォルトでは terminate() に逝く。

278 名前:デフォルトの名無しさん :2006/07/23(日) 16:26:40
vcでは例外指定は無効だけどね

279 名前:デフォルトの名無しさん :2006/07/23(日) 16:57:00
いや、VC++でもthrow()だけは有効だった気がする。。

280 名前:デフォルトの名無しさん :2006/07/23(日) 17:09:30
派生クラスにも基底クラスにも同名のメソッドがあります。
virtual メソッドではありません。派生クラスのなかから
基底クラスのメソッドを明示的に示して呼び出したいのですが
どのようにすればよいのでしょうか?

Java の super のようなキーワードに相当することを
やりたいと思っています。

281 名前:デフォルトの名無しさん :2006/07/23(日) 17:14:50
基底クラス名::メソッド名(...)

282 名前:デフォルトの名無しさん :2006/07/23(日) 17:22:02
>>281 ありがとうございます。
なるほど、C++ では多重継承が許されているため
super というような記述は用意されていないのですね。


283 名前:デフォルトの名無しさん :2006/07/23(日) 17:32:56
D&Eによると、inheritedというキーワードが提案されたが、
「自分でtypedefすればできる、だからこんなことでC++を肥大化させることないだろ」
ということになって、規格から外されたそうだ。

class foreman : public employee {
    typedef empolyee inherited;
    // ...
    void print();
};

class manager : public foreman {
    typedef foreman inherited;
    // ...
    void print();
};

void managaer::print()
{
    inherited::print();
    // ...
}

284 名前:デフォルトの名無しさん :2006/07/23(日) 17:41:41
また出たw
はいはい、設計と進化最近よんだんでちゅね。
披露ご苦労さん。

285 名前:デフォルトの名無しさん :2006/07/23(日) 17:43:35
しかも微妙に文意を間違えてるし。ダメだこいつ。

286 名前:デフォルトの名無しさん :2006/07/23(日) 17:58:48
2chの夏、厨房の夏


287 名前:デフォルトの名無しさん :2006/07/23(日) 18:03:16
知識厨ウザス

288 名前:デフォルトの名無しさん :2006/07/23(日) 18:08:36
>>284みたいに言いたくなるときがここ最近クソ多いが、
>>283は知らなかったから今回はグッジョブと言いたい

289 名前:デフォルトの名無しさん :2006/07/23(日) 18:09:37
と思ったけど、これが仮想関数だった場合問題になるんじゃねぇの?>inherited
usingした方がいいような気がする

290 名前:デフォルトの名無しさん :2006/07/23(日) 18:35:03
何いってんだお前。

291 名前:デフォルトの名無しさん :2006/07/23(日) 20:04:36
>>283
IBMのOCLががんがん使ってたな。


292 名前:デフォルトの名無しさん :2006/07/23(日) 20:07:50
質問者はちゃんと理解したのになw

293 名前:デフォルトの名無しさん :2006/07/23(日) 22:16:30
>>279
いや、試したがだめだな

294 名前:デフォルトの名無しさん :2006/07/23(日) 23:50:09
>>293
どうダメだったの?

295 名前:デフォルトの名無しさん :2006/07/24(月) 00:08:31
gccだとthrow()指定してるときちんとアボートするけど
vcはthrow指定しても普通にcatchに飛んで続行したよ

296 名前:デフォルトの名無しさん :2006/07/24(月) 00:16:01
結論:VCは糞。GCCマンセー。

297 名前:デフォルトの名無しさん :2006/07/24(月) 00:23:44
そもそもVCのthrow()は、最適化のためにあるだけだしな。

298 名前:デフォルトの名無しさん :2006/07/24(月) 00:32:24
まあ微妙に標準規格からずれるのはMSのいつもの話だよね。
ただ、C++の例外指定はもう仕様に難があると思うし、きちんと
使ってる人もそんなにいるとも思えないしどうでもいいのかもね。

299 名前:デフォルトの名無しさん :2006/07/24(月) 00:40:28
>>298
個人的にはいっそのこと廃止して欲しい。
そしたら throw を心置きなくマクロで弄れる。
(例外の発生箇所の__FILE__と__LINE__をログに吐ける。)

300 名前:デフォルトの名無しさん :2006/07/24(月) 00:48:08
>>299
予約語をマクロで弄るのはヨクナイコトデスヨー

301 名前:デフォルトの名無しさん :2006/07/24(月) 00:53:54
>>299
アドレスわかれば、どこか特定できるでしょ

302 名前:デフォルトの名無しさん :2006/07/24(月) 01:12:16
>>300
そこが悩みの種

>>301
見ただけで分かる>>>>(越えられない壁)>>>>調べれば分かる

303 名前:デフォルトの名無しさん :2006/07/24(月) 01:54:48
#define THROW ほにゃらら・・・・

でいいんじゃないの?
throw そのままマクロにしなくても。

304 名前:デフォルトの名無しさん :2006/07/24(月) 02:00:30
>>303
やっぱ、やるならそっちかなぁ。
ソース見てて頻繁に出現する俺マクロってなんかやなんだけどなぁ。
でも、他人の目から見てもコッソリ予約語が置換されるよりは
俺マクロが頻繁に出現するほうがまだましか。

305 名前:デフォルトの名無しさん :2006/07/24(月) 02:14:56
>>300
うーん、俺も予約語がマクロで見えなくなるのはやだから結局
throw MyException(MY_EXCEPTION_INFO);
みたいな感じにしてるなあ。
ただ、やっぱスタックトレースで取れないとそこだけ情報取れても
役に立つことがあまりないかなあ。。
某ゲームのコードで全関数の最初と終わりにguard/unguardみたいに
仕込んでるのあったけど、あれもあれでちょっと問題あるし。
例外周りは悩みが尽きない。

306 名前:デフォルトの名無しさん :2006/07/24(月) 15:41:47
>>183
「Containerに入れるには」、Assignableじゃないといけない。23.1.3
Assignableであるには、返り値の型は参照でないといけない。23.1.4


307 名前:デフォルトの名無しさん :2006/07/24(月) 20:01:53
Effective C++ 34項後半に、ファクトリ関数なるものが紹介されています。
Person* pp = makePerson(...);
// ppを使う
delete pp;

これは、makePersonにnewしてもらう一方で、呼出し側がdeleteする責任を負うので、
31項の教え「関数は、(中略)関数の中でnewで初期化したポインタの参照先を返してはならない」
に反する気がして、気になっています。

・deleteの手間がかかるので、オブジェクトをnewして返すのは原則ダメ
・でもファクトリ関数として使うなら、やや危険だが便利なので気をつけて使え
という解釈でいいのでしょうか?

308 名前:デフォルトの名無しさん :2006/07/24(月) 21:43:38
簡単のためにそうした、という解釈は納得できない?

309 名前:デフォルトの名無しさん :2006/07/24(月) 21:50:44
>>307
EffectiveC++の3版を読むといいと思うよ


310 名前:デフォルトの名無しさん :2006/07/24(月) 22:10:53
>>307
参照返してないじゃん。

というか、
> ポインタの参照先を返
誤訳?

311 名前:デフォルトの名無しさん :2006/07/24(月) 23:25:38
↑バカはスルー

312 名前:デフォルトの名無しさん :2006/07/25(火) 01:03:22
例外使え使えって言われるけどエラー表示して終了するだけの
コードしか見たことがない俺ガイル

313 名前:デフォルトの名無しさん :2006/07/25(火) 01:11:31
例外がスルーされまくりなコードの保守をさせられたときがある。
五指に入るくらい最悪なコードだった。

314 名前:デフォルトの名無しさん :2006/07/25(火) 01:20:56
>>312
俺もそんな使い方しかしていない。
下手したらcatchはmainの中だけ。

315 名前:デフォルトの名無しさん :2006/07/25(火) 01:21:52
コンテナを内部に持つクラスを設計してるのですが、
インターフェースと実装を分けるべく、以下のようにしてみました。
趣旨は具体的に使用するコンテナを隠すことなのですが、
なんとなく※1の部分が気持ち悪いのです。
気持ち悪いという感覚は捨てていいのでしょうか?それともまずい設計でしょうか?

ヘッダー
class hoge {
template <typename C> // Cはコンテナ型
class iterator_gen : public C::iterator { 適当な定義 };
class container;
typedef iterator_gen<container> iterator;
virtual iterator begin(void) = 0;
virtual iterator end(void) = 0;
};

実装
class hoge_impl {
class container : public vector<int> { 中身なし }; // ※1
iterator begin(void) { return m_cnt.begin(); }
iterator end(void) { return m_cnt.end(); }
private:
container m_cnt;
};


316 名前:デフォルトの名無しさん :2006/07/25(火) 03:29:38
>>315
コンパイルできるんなら、いいんじゃない?
きっと iterator_gen の「適当な定義」が魔法みたいなコードなんだろう。

317 名前:315 :2006/07/25(火) 03:47:41
>>316
どうも。
コンパイルできるという方針のみに従えば、大抵のコードはOKになってしまうと思います…。
他にこういうことしたことある人いないかなと。もしいなければなぜかなと。

> きっと iterator_gen の「適当な定義」が魔法みたいなコードなんだろう。
iterator_genはそんなに突飛なものではなくて、
↓みたいな適当なコンストラクタの定義と
 typedef typename C::iterator base;
 iterator(void) : base() {}
 iterator(base_t i_) : base(i_) {}
あとはdereferenceやincrement演算を若干変更しているだけです。


318 名前:デフォルトの名無しさん :2006/07/25(火) 04:21:54
>>317
それ、
 hoge::iterator i;
って変数定義しようとしたら C::iterator の定義が要るだろ。
hoge_impl::container の定義が見えてるところじゃないと
コンパイルできないはずだが、それでいいの?

319 名前:315 :2006/07/25(火) 05:00:54
っあーー。
>>318さんの仰るとおりです。
実装部分だけテストしていてスルーしてました。
通りませんね。

// ヘッダー(hoge.h)
class hoge {
public:
template <typename C>
struct iterator_gen : public C::iterator {
typedef typename C::iterator base;
iterator_gen(void) : base() {}
iterator_gen(base i_) : base(i_) {}
};
class container;
typedef iterator_gen<container> iterator;
virtual iterator func(void) = 0;
static hoge* create(void);
};

// 実装(hoge_impl.cpp)
#include <vector>
#include "hoge.h"
class hoge::container : public std::vector<int> {};
class hoge_impl : public hoge {
public:
iterator func(void) { return m_cnt.begin(); }
std::vector<int> m_cnt;
};
hoge* hoge::create(void) { return new hoge_impl; }


320 名前:315 :2006/07/25(火) 05:02:20
つづき

// サンプル
#include "hoge.h"
int main(void) {
hoge* p = hoge::create();
hoge::iterator i = p->func(); // ★当然通らない…★
return 0;
}


321 名前:315 :2006/07/25(火) 05:06:18
>>316さんも>>318さんの指摘と同じだったのですね。恥ずかしい…。
ところでコンテナを実装に隠しながらイテレータを返すインターフェースを
実現する方法ってないもんでしょうか…。


322 名前:デフォルトの名無しさん :2006/07/25(火) 05:16:08
>>321
仮想関数(みたいなの)使ったイテレータを自前で定義するしか無さそうだね。

一般的な設計の話にすれば、イテレータを使うような操作を
コンテナを持つクラスのメンバ関数にすることを先に検討するべき。
イテレータで可能な操作のすべてが必要なケースなんてあんまり無い。

323 名前:315 :2006/07/25(火) 06:14:33
やっぱり自前定義しかないですよね。

class iterator {
public:
インターフェースいろいろ
private:
class iterator_impl;
iterator_impl* m_impl;
};

class iterator::iterator_impl : public 任意のコンテナ::iterator {
実装いろいろ
};

みたいにするのが楽なのかなぁ。

> イテレータを使うような操作をコンテナを持つクラスのメンバ関数にすることを先に検討するべき。

なるほど。なんとなく理解できます。
でも今回はコンテナを内部に複数持つクラスを柔軟にSTLのアルゴリズム等に渡したいなぁと。
たとえば
int xsum = std::accumulate(p->xbegin(),p->xend());
int ysum = std::accumulate(p->ybegin(),p->yend());
int zsum = std::accumulate(p->zbegin(),p->zend());
みたいに。

324 名前:デフォルトの名無しさん :2006/07/25(火) 08:26:44
(機械的にできるという意味で)一番簡単なのは、
private継承して、メンバー関数を全部baseのメンバー関数を呼び出すように
オーバーライドすることだろうけど、それでも百万年早そうだからあきらめろ。

325 名前:307 :2006/07/25(火) 11:06:57
お返事ありがとうございます。

>>308
すみません、ちょっとよくわからないのですが、
「本当はいけないコーディングだけど、簡単にファクトリ関数を説明するためにそう書いた」
という意味でしょうか?

>>309
確かに私のは第2版でした。書き忘れてすみません。
今度本屋に行って読んでみます

326 名前:デフォルトの名無しさん :2006/07/25(火) 11:08:20
逆アセするときどんなソフト使ってるか教えて

327 名前:デフォルトの名無しさん :2006/07/25(火) 11:21:42
>>324
百万年早いなんて陳腐な表現平気で使うし
オマケに日本語間違ってるし

328 名前:デフォルトの名無しさん :2006/07/25(火) 11:47:54
>>323
> でも今回はコンテナを内部に複数持つクラスを柔軟にSTLのアルゴリズム等に渡したいなぁと。
> たとえば

挙げられた例に説得力が無いな。
hoge に virtual int xsum() const; とか用意しろよ、と思ってしまう。
まぁうまく書き表せなかっただけなんだろうけど。

329 名前:デフォルトの名無しさん :2006/07/25(火) 13:58:38
そもそもSTLのようなテンプレートをふんだんに使うコードと、
319がやろうとしている実装の分離とは相性が悪いから、
どこかで無理が出てきたり気持ち悪くなってくるのは仕方がない。

こういうときにboost::functionのイテレータ版があればいいなとは思う。
それがあったとしても、その実装は結局322が言っていることと同じことになるはずなんだけどね。

330 名前:デフォルトの名無しさん :2006/07/25(火) 14:02:26
boost馬鹿

331 名前:デフォルトの名無しさん :2006/07/25(火) 14:05:35
boost馬鹿の俺が来ましたよ。
iterator_facadeで一挙解決!

332 名前:315 :2006/07/25(火) 16:04:01
>>324
結局全部(機械的に)書くことになるわけですね。

>>329
> そもそもSTLのようなテンプレートをふんだんに使うコードと、
> 319がやろうとしている実装の分離とは相性が悪いから、
それを痛感してます('A`)
インターフェイスとなる基本クラスXと実装X_impl、
Xの宣言をincludeしたテンプレートクラスX_tmpl(実装の大部分はX_implを流用)、
という構成を目指していたのですが、難しいです。

>>328
>挙げられた例に説得力が無いな。
はい…すみません。コンテナの中身はそれぞれ独自メソッドを持った自前クラスで、
シーケンシャルにコンテナ要素に対して特定の操作を行いたい、
かつその操作の種類を今後どんどん増やすという状況です。


333 名前:デフォルトの名無しさん :2006/07/25(火) 16:07:40
public継承して、
隠したいところだけprivateで宣言しとけば?

けどalgorithmを適用する時に面倒なことが起きがち。
特に名前ルックアップで

334 名前:デフォルトの名無しさん :2006/07/25(火) 17:13:06
>>329
iterator のレベルの操作で実装を完全に隠蔽しようと(型を消そうと)すると,
たいていの場合効率の面で許容できない実装になるような気がします.
(例えば,ポインタのインクリメント1つに関数呼び出しが常に生じる)

それでも構わないというなら一応できなくはないと思います.
value_type (reference) の型情報はインタフェースの型安全性を支配するので
この型情報は消せないですが,それ以外の型を消去した
実行時多相のイテレータクラスは作成できるかと思います.

template< class Reference >
class any_iterator
{
......
};

などのような形で, Reference 型が一致する全てのイテレータ型を run-time で
多相的に扱えるようなイテレータクラスを作成できるかと思います.実装技術的には
広く Boost で使用されている Type Erasure という技術でできると思います.

ただ1点だけ難儀があるとすれば, operator==, operator!= などの2項の比較関数において,
異なるイテレータ型の間での inter-operability が存在するので,
厳密にこれ対処しようとすると run-time double dispatch をエミュレートしないといけない,
という問題はあるかと思います.

335 名前:デフォルトの名無しさん :2006/07/25(火) 18:43:08
横から失礼

>>332
>結局全部(機械的に)書くことになるわけですね。
使うやつだけusingすれば?
iteratorはbaseのやつをtypedefでぱくっちゃうとか


336 名前:315 :2006/07/25(火) 21:48:44
>>333
いずれにせよヘッダー内にコンテナが「見える」わけですね??
いえ…全然まずくないのですが。

>>334
> たいていの場合効率の面で許容できない実装になるような気がします.
そうですね…。仮想関数にせよハンドルを使うにせよ、
間接アクセスのコストがちょっと想像できません。
でも、なんとなくコンテナ要素に対する操作がボトルネックになりそうなので、
イテレートのオーバーヘッドは無視してもよさそうな気もしてます。
(そのおかげで気持ちよい実装になるならば、ですが)

Type Erasureもdouble dispatchも初見でした…。
Type Erasureというのはpimplをテンプレート化したみたいなものでしょうか。
double dispatchは相方の型がわからなくても、相方の仮想関数を使って
自分と比較すればOKということですね。スゴイですね…。

…あんまり頑張らなくていい気がしてきました(´・з・`)

>>335
そうする場合にはそういうことも含めていろいろありだと思います。
どうもでした!

337 名前:デフォルトの名無しさん :2006/07/25(火) 23:50:57
iterator_facedeは検討しないの?

338 名前:デフォルトの名無しさん :2006/07/26(水) 18:05:05
boost馬鹿の俺が来ましたよ。
iterator_facadeで一挙解決!

339 名前:315 :2006/07/27(木) 09:45:25
iterator_facade、まだあんまり理解してませんが、
ちょろりと見た感じ「機械的に書く」ことを勝手にやってくれると理解しましたが…。
つまり表面を用意してはくれるけれど、中身(ポインタとか)はこちらで決めてくださいよと。
その中身に例えばコンテナのイテレータを使うとすれば、
結局コンテナが見えちゃうわけですよね。

うーん、何か勘違いしている気もしつつ…


340 名前:デフォルトの名無しさん :2006/07/27(木) 17:17:35
iterater_facadeは最小限の記述でiteratorを生成してくれるので、
type erasureやpimplを使う時でも有効だと思います。



341 名前:デフォルトの名無しさん :2006/07/27(木) 19:21:41
まだ勉強はじめたばっかりのものなんですが、
いまはVisualCでコンパイルしてるんですが、Linuxの環境でコンパイルすれば
Linux用のソフトになるんですか?

342 名前:デフォルトの名無しさん :2006/07/27(木) 19:36:17
>>341
互換性を意識して注意深くコーディングすれば可能。
hello world くらいなら全然OK。

343 名前:デフォルトの名無しさん :2006/07/27(木) 21:26:14
レガシーなAPI hogeに出力引数としてvectorを渡しています

void hoge(void* buf,size_t& written_size)
vector<char> v;
size_t written_size;
v.resize(500);//500はAPI hogeが書き込む可能性のある最大の長さ
hoge(&v[0],&written_size);
このままだとvは自分の長さを知らないため、
v.resize(written_size);
としているんですが、最後のresize()で
内部のバッファのアドレスが変わってしまう可能性はあるんでしょうか
hogeが内部でバッファのアドレスを保持して使うので、
アドレスが変わってしまうとヤバスです
今のところ無事に動いてるのですが・・・
最後のresizeで前の状態より長さが大きくなる事はないので
大丈夫かとは思うんですが 実装によりけり?


344 名前:デフォルトの名無しさん :2006/07/27(木) 21:43:28
>>343
ヤバい予感。少なくとも標準では保証外。

§23.2.4.6
void resize(size_type sz, T c = T());
6 Effects:
if (sz > size())
insert(end(), sz-size(), c);
else if (sz < size())
erase(begin()+sz, end());
else
; //do nothing

§23.2.4.3.2
iterator erase(iterator position);
iterator erase(iterator first, iterator last);
3 Effects: Invalidates all the iterators and references after the point of the erase.
4 Complexity: The destructor of T is called the number of times equal to the number of the elements erased,
but the assignment operator of T is called the number of times equal to the number of elements in the
vector after the erased elements.
5 Throws: Nothing unless an exception is thrown by the copy constructor or assignment operator of T.


345 名前:デフォルトの名無しさん :2006/07/27(木) 22:18:55
つーかresize()後にもっぺんポインタ取得しなおせばいいと思うんだが。

346 名前:デフォルトの名無しさん :2006/07/27(木) 22:26:19
>>344
やはりですか。
eraseの呼び出しでポインタが無効化してしまう可能性があるという事すね
>>345
hoge関数は説明のために簡略化してますが、
hoge関数は内部で渡されたbufのアドレスを保持して、
後々別の関数で使ったりしているのです


素直にchar配列を使うべきかな・・・


347 名前:デフォルトの名無しさん :2006/07/27(木) 22:56:18
>>346
つーか、なぜにresize()が必要なんだ?
仮想的なend()が欲しければ、v.begin() + written_sizeをv.end()の代わりに使えばいい。
v.size()が必要なら、writen_sizeを覚えておく……これは確かにあれか……。

348 名前:デフォルトの名無しさん :2006/07/27(木) 23:02:24
ちうかまあ、その辺だとboostに転がってるスマートポインタ使ったほうがいいと思うが。

349 名前:デフォルトの名無しさん :2006/07/27(木) 23:38:36
boost使うと変なおまけがいっぱいついてくるからやだ

350 名前:デフォルトの名無しさん :2006/07/28(金) 00:22:34
>>348 何の話だ?

351 名前:デフォルトの名無しさん :2006/07/28(金) 00:28:31
>>344
> 3 Effects: Invalidates all the iterators and references after the point of the erase.

"after the point of the erase" ってことは、削除した場所より前は
大丈夫なんじゃないの?

352 名前:351 :2006/07/28(金) 00:37:15
こんなん見つけた。
http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#414

やっぱり削除した場所より前は大丈夫。
ってことで >>343 も大丈夫。

353 名前:デフォルトの名無しさん :2006/07/28(金) 10:19:14
>>342
ありがとうございました。
Linuxにも興味があるので。

354 名前:デフォルトの名無しさん :2006/07/29(土) 12:32:52
http://www.kumei.ne.jp/c_lang/bcc/bcc_03.htm
に載ってるようにbcc32 -w-8057 -eRelease\win01.exe win01.cpp
でやっても
Error: 外部シンボル '_main' が未解決(C:\BORLAND\BCC55\LIB\C0X32.OBJ が参照)
と出るんですが何処がおかしいんでしょうか

355 名前:デフォルトの名無しさん :2006/07/29(土) 12:38:15
載ってるようにやってないから

356 名前:デフォルトの名無しさん :2006/07/29(土) 12:48:01
-Wはどこいったの?

357 名前:デフォルトの名無しさん :2006/07/29(土) 12:52:13
エラー E2075: コマンドライン オプションの間違い : -W -eRelease\win01.exe

358 名前:デフォルトの名無しさん :2006/07/29(土) 12:58:14
全角スペース

359 名前:デフォルトの名無しさん :2006/07/29(土) 13:03:38
>>358
あっできた・・・・どうもありがとうございます

360 名前:デフォルトの名無しさん :2006/07/29(土) 16:40:28
ただでさえ遅いSTLのIteratorに仮想関数なんてつけたら
使い物にならなくなりそうだ。。
試してみたが、string::iteratorと生ポインタでは10倍くらい
速度が違うよ。

361 名前:デフォルトの名無しさん :2006/07/29(土) 17:19:33
んなもの条件によって大きく変わる

362 名前:デフォルトの名無しさん :2006/07/29(土) 17:29:09
1つの調査結果で解った気になる。
ゆとり世代にはよくあること。

363 名前:デフォルトの名無しさん :2006/07/29(土) 17:29:53
メモリ操作とかの場合は効いてくるよ

364 名前:デフォルトの名無しさん :2006/07/29(土) 17:33:34
適材適所
なんのためのマルチパラダイム言語なのかと

365 名前:デフォルトの名無しさん :2006/07/29(土) 17:51:19
>適材適所
ま、そうだね。ディスクアクセスしてるときはiteratorが遅いなんて
計算量のオーダーが違うから問題にならないし。
ただ、もっとも下位のアルゴリズムライブラリはあらゆる使われ方を
想定して高速である義務があると思う。

366 名前:デフォルトの名無しさん :2006/07/29(土) 17:56:27
計算量?

367 名前:デフォルトの名無しさん :2006/07/29(土) 18:13:17
何の話やねん。

368 名前:デフォルトの名無しさん :2006/07/29(土) 18:14:35
>>360
最適化かけたか?

369 名前:デフォルトの名無しさん :2006/07/29(土) 18:17:06
難しいことを書こうとして自爆した例

370 名前:デフォルトの名無しさん :2006/07/29(土) 18:44:44
>368
かけたよ。でも、書き方によっては最適化されて消えてしまう場合も
あるから難しいね。パフォーマンス測定のいい書き方あったら教えてくれ。
>366,369
あれ?なんか否定的?基礎ライブラリは速いほうがいいよねという普通の
ことを言っただけのつもりだったが・・

371 名前:デフォルトの名無しさん :2006/07/29(土) 19:14:07
ようは
for(int j = 0; j < size; ++j){

for(ite = s.begin(); ite != s.end(); ++ite){
これは結構差が出る。
operator++が動いてendでコピーコンストラクタが動いて・・だから

372 名前:デフォルトの名無しさん :2006/07/29(土) 19:34:35
えー?

373 名前:デフォルトの名無しさん :2006/07/29(土) 19:42:21
細かいけれど普通こうしませんか?
ite pos = s.begin();
ite end = s.end();
for(; pos!=end; ++pos) {


374 名前:デフォルトの名無しさん :2006/07/29(土) 20:14:02
std::stringの実装はstd::vector風だとは限らない。

375 名前:デフォルトの名無しさん :2006/07/29(土) 20:23:54
でも、
for(int j = 0; j < size; ++j){
毎秒100回とかの処理(ディスクに書き込みとか)
}
for(ite = s.begin(); ite != s.end(); ++ite){
毎秒100回とかの処理(ディスクに書き込みとか)
}
とかは毎秒100回のオーダーが効いてくるからiteratorの遅さは
出てこない、というようなことを言いたかったのだが。

>>374
少なくともVCのstlは普通にoperator++が動いてendでコピー
コンストラクタが動くよ。xstringのソース見るとわかるけど普通に書いてる。

376 名前:デフォルトの名無しさん :2006/07/29(土) 20:28:46
「コピー」コンストラクタじゃないだろ。

377 名前:デフォルトの名無しさん :2006/07/29(土) 21:07:51
まぁ、
for (std::vector<int>::const_iterator it = v.begin(); it != v.end(); ++it) {
sum += * it;
}
くらいなら
for (int ic = 0; ic < end; ++ic) {
sum += a[ic];
}
と同じ程度のコードを吐くコンパイラくらいいくらでもあるだろ。

378 名前:デフォルトの名無しさん :2006/07/29(土) 21:25:21
中途半端な知識の奴、ウザいぞ。

379 名前:デフォルトの名無しさん :2006/07/29(土) 21:31:16
その辺のトレードオフをプログラマの裁量で
決定できるのがC++の魅力だと思います先生

380 名前:デフォルトの名無しさん :2006/07/29(土) 22:03:32
>>375
>xstringのソース見るとわかるけど普通に書いてる。
なんだこいつ初心者か。「普通に書いてる」からなんだよバカが。

たとえソースコード上に書いてあったとしても、
最適化により、書いて無いのと同じ速度で動く可能性も知らんのか。

事実、以下のコードはまったく同じ速度で動いてる。vcでな。
まず最適化の掛け方勉強しとけ。

#include <string>
#include <numeric>
void test(){
std::string str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
int n = 10000000;
{
boost::timer t;
int sum = 0;
for(int i=0; i<n; ++i){
sum = std::accumulate(str.begin(), str.end(), sum);
}
printf("%d %g\n", sum, t.elapsed());
}
{
boost::timer t;
int sum = 0;
for(int i=0; i<n; ++i){
sum = std::accumulate(str.c_str(), str.c_str()+str.size(), sum);
}
printf("%d %g\n", sum, t.elapsed());
}
}

381 名前:デフォルトの名無しさん :2006/07/29(土) 22:32:47
なんでキレてるんだ?

382 名前:デフォルトの名無しさん :2006/07/29(土) 22:34:09
弱い犬ほどキャンキャン吼えるって言うしな

383 名前:デフォルトの名無しさん :2006/07/29(土) 22:40:35
↑最適化の仕方もしらん糞の遠吠え

384 名前:デフォルトの名無しさん :2006/07/29(土) 22:49:05
>>380
accumulateは
_Ty accumulate(_InIt _First, _InIt _Last, _Ty _Val)
{// return sum of _Val and all in [_First, _Last)
for (; _First != _Last; ++_First)
_Val = _Val + *_First;
return (_Val);
}
なので、380のコードはiteratorと生ポインタの比較にはなってないよ。

385 名前:デフォルトの名無しさん :2006/07/29(土) 22:51:22
いいんだよ
「呼吸するようにboost使っててかっこいいですね」
とでも褒めておいて放置しとけ

386 名前:デフォルトの名無しさん :2006/07/29(土) 22:56:37
>>384
は?どう見てもiteratorと生ポインタの比較になってるけど。
_InItの型が何になるか分からないの?

>>385
使えない劣等感を感じるぐらいなら勉強しろよ。



387 名前:デフォルトの名無しさん :2006/07/29(土) 22:59:48
>>385
へ?

388 名前:デフォルトの名無しさん :2006/07/29(土) 23:01:39
STLのイテレータって遅いんだろうか
そりゃ生ポインタに比べれば遅いんだろうけど

389 名前:デフォルトの名無しさん :2006/07/29(土) 23:03:01
同じだった、って書き込まれたすぐ後にコレだ

390 名前:388 :2006/07/29(土) 23:10:44
いや最適化は考えない場合
ポインタに比べどういうオーバヘッドが生じるのかなと

391 名前:デフォルトの名無しさん :2006/07/29(土) 23:27:58
>>390
最適か考えないんなら、ソース見ればわかるだろ。意味があるとは思わんが。

392 名前:デフォルトの名無しさん :2006/07/29(土) 23:29:58
accumelateじゃなくってメモリへの代入とか比較とかの
場合に差がでるんじゃね?
そっちでもっかいやってよ >> 380

393 名前:デフォルトの名無しさん :2006/07/29(土) 23:30:51
boost馬鹿うぜえ

394 名前:デフォルトの名無しさん :2006/07/29(土) 23:33:15
>>392
自分でやれ

395 名前:デフォルトの名無しさん :2006/07/29(土) 23:36:34
知識披露厨きんもーっ

396 名前:デフォルトの名無しさん :2006/07/29(土) 23:59:01
これは ひどい

397 名前:デフォルトの名無しさん :2006/07/30(日) 00:41:55
速度とか最適化とか考えると泥沼にはまるのもC++の仕様

398 名前:デフォルトの名無しさん :2006/07/30(日) 01:24:01
試してみた

#include <string>
#include <windows.h>
using namespace std;

int main(){
strings;
string::iterator ite;
const int count = 1000000;
const int size = 1000;
DWORD start;
int found = 0;

for(int i = 0; i < size; ++i){
s += "a";
}

// iterator書き込み
start = GetTickCount();
for(int i = 0; i < count; ++i){
for(ite = s.begin(); ite != s.end(); ++ite){
*ite = 0;
}
}
printf("iterator書き込み msec=%d\n", GetTickCount() - start);


399 名前:デフォルトの名無しさん :2006/07/30(日) 01:25:10
続き

// iterator検索
s[size - 1] = 'b';
found = 0;
start = GetTickCount();
for(int i = 0; i < count; ++i){
for(ite = s.begin(); ite != s.end(); ++ite){
if(*ite == 'b'){
++found;
break;
}
}
}
printf("iterator検索 msec=%d, count=%d\n", GetTickCount() - start, found);

// ポインタ書き込み
char p[size];
start = GetTickCount();
for(int i = 0; i < count; ++i){
for(int j = 0; j < size; ++j){
p[j] = 'a';
}
}
printf("ポインタ書き込み msec=%d\n", GetTickCount() - start);


400 名前:デフォルトの名無しさん :2006/07/30(日) 01:26:24
続き
// ポインタ検索
p[size - 1] = 'b';
found = 0;
start = GetTickCount();
for(int i = 0; i < count; ++i){
for(int j = 0; j < size; ++j){
if(p[j] == 'b'){
++found;
break;
}
}
}
printf("ポインタ検索 msec=%d, count=%d\n", GetTickCount() - start, found);
}

401 名前:デフォルトの名無しさん :2006/07/30(日) 01:27:59
もう続けなくていいぞ。

402 名前:デフォルトの名無しさん :2006/07/30(日) 01:30:16
結果
iterator書き込み msec=3594
iterator検索 msec=4203
ポインタ書き込み msec=94
ポインタ検索 msec=1891
微妙にポインタの方が速いのかな。
あれ、でもポインタ書き込みは速すぎだな、最適化で飛ばされちゃったかな。
まあなんにしてもそれほど差はないのかな。

403 名前:デフォルトの名無しさん :2006/07/30(日) 01:35:35
まともな考察もできないのに、ゴミコード貼る馬鹿

404 名前:デフォルトの名無しさん :2006/07/30(日) 01:36:50
んじゃやって

405 名前:デフォルトの名無しさん :2006/07/30(日) 01:41:36
やだもーん
ぼくはやだもんねーだ

406 名前:デフォルトの名無しさん :2006/07/30(日) 01:45:19
んじゃもういいや、iteratorは十分高速ということで終了

407 名前:デフォルトの名無しさん :2006/07/30(日) 01:46:16
さすがC++だね

408 名前:デフォルトの名無しさん :2006/07/30(日) 03:42:07
>>37
なぜ外で宣言する?
フツーこうだろ?
for(ite i = s.begin(), end = s.end(); i != end; ++i) {

409 名前:デフォルトの名無しさん :2006/07/30(日) 04:36:18
どうでもいい

410 名前:デフォルトの名無しさん :2006/07/30(日) 05:33:29
>>373
>>377


411 名前:デフォルトの名無しさん :2006/07/30(日) 06:30:04
こうして、iteratorは遅いというアホな知識を得た人間が増えたのであった。

412 名前:デフォルトの名無しさん :2006/07/30(日) 07:46:54
んなことない。
iteratorはちょーはえーが生ポインタと比べるともしかしたらちょっと
くらい遅いかもねくらいでもういいよ。それ以上誰も証明できねーし。

413 名前:デフォルトの名無しさん :2006/07/30(日) 08:12:02
iteratorが遅いと思うんなら生ポインタでalgorithm呼べばいいやん。
ちゃんとコンパイルできるんやし。

414 名前:デフォルトの名無しさん :2006/07/30(日) 08:47:10
例えばstd::find()は自前のforループと同じコードに落とせるしね。

415 名前:デフォルトの名無しさん :2006/07/30(日) 08:53:11
急激に糞スレ化が進んでいます。

416 名前:デフォルトの名無しさん :2006/07/30(日) 12:42:13
仕様です。

417 名前:デフォルトの名無しさん :2006/07/30(日) 14:32:34
>>398
なんでend()を終了判定のたびにコンストラクトしているんだ?
end()はconstじゃないぞ?

418 名前:デフォルトの名無しさん :2006/07/30(日) 14:45:22
>>417 >>409

419 名前:デフォルトの名無しさん :2006/07/31(月) 09:14:24
最適化したい奴はそうしろ。
保守性を重視したい奴はそうしろ。
ただし、富豪主義なんてプログラマの泣き言でしかないのを忘れるな。

420 名前:デフォルトの名無しさん :2006/07/31(月) 09:44:31
個人を特定されかねない超訳単語のご利用はお控え下さい。

421 名前:デフォルトの名無しさん :2006/07/31(月) 11:19:41
富豪とか、古くは大名とかって
一時期流行ったし、個人を特定するほど出はないと思うがなあ

422 名前:デフォルトの名無しさん :2006/07/31(月) 14:50:40
俺も似たことしてみたがmemory上の検索でもほとんど差はでなかったね。
ただ、
for (ite = s.begin(); ite != s.end(); ++ite){
for (ite = s.begin(), end = s.end(); ite != end; ++ite){
は30%くらい差が出た。
アセンブリ見たら下の方がいいコードが吐かれたわ
この程度最適化されると思ったが

423 名前:デフォルトの名無しさん :2006/07/31(月) 14:55:27
>>422
つか、上と下じゃ意味が違うし。

424 名前:デフォルトの名無しさん :2006/07/31(月) 15:01:46
>>422
それじゃ、end()の値が変動する可能性のあるコンテナには下の書き方は
使えないじゃん。

425 名前:デフォルトの名無しさん :2006/07/31(月) 15:29:37
>>422
そういうことはコンパイラのバージョンと指定したオプションを明示した上で言ってくれ。

426 名前:デフォルトの名無しさん :2006/07/31(月) 15:45:08
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
オプションは/O2だけでいいな


427 名前:デフォルトの名無しさん :2006/07/31(月) 16:17:14
>>424
何を当たり前の事を言ってるのだろうか。

428 名前:デフォルトの名無しさん :2006/07/31(月) 16:24:05
>>427
いや、お前が低脳そうに見えたんで、一応書いておいたんだけどな。

429 名前:デフォルトの名無しさん :2006/07/31(月) 16:43:35
>>422=>>427だったらマジワロスだなw

430 名前:デフォルトの名無しさん :2006/07/31(月) 17:53:20
どうせベンチマーク馬鹿だろうさ。
環境も明示せずに。

431 名前:デフォルトの名無しさん :2006/07/31(月) 18:55:36
間抜けな>>422がいると聞いて、ぶっ飛んできました

432 名前:デフォルトの名無しさん :2006/07/31(月) 18:56:45
>>424
もしかしてホンキでそれを言ってるのか…?

433 名前:デフォルトの名無しさん :2006/07/31(月) 19:03:15
「end()の値が変動する可能性のあるコンテナ」があると聞いて飛んできました

434 名前:デフォルトの名無しさん :2006/07/31(月) 19:06:24
ループ内でinsert()やったら平気でend()が変わるだろうが。糞が。

435 名前:デフォルトの名無しさん :2006/07/31(月) 19:12:11
誰か>>434に何か言ってやれよ。

436 名前:デフォルトの名無しさん :2006/07/31(月) 19:21:54
超初心者なんで、質問の仕方が悪いかもしれませんが教えて下さい。

配列変数がn種類あり、(array_1[]〜array_n[])これらの値ををそれぞれ、
n種類のファイル(file_1〜file_n)に書き込みたいです。

つまり、array_k[]の値を全てfile_kに書き込む。(ただし、k=0・・n)
ここで、書き込むルーチンは全ての配列変数で同じことをやりたい。

従って、array_kをfile_kに書き込むルーチンを書けば、あとはkの値を1〜nまで繰り返せば良いと思うのですが、反復文を使って、変数名及びファイル名のみを変化させながら同じルーチンを繰り返す方法が分かりません。

ヒント:〜関数
といった程度で良いので、回答下さい!お礼は体で払います。

437 名前:デフォルトの名無しさん :2006/07/31(月) 19:28:29
>>434
[begin, end) なループ内で insert なんかしたら、
end どころか、Iterator そのものが無効になる可能性があるだろ。
まさか、↓みたいなコーディングしてんのか?

for( iter it=c.begin(); it!=c.end(); ++it )
{
 ...
 if( condition )
 {
  it = c.insert( it, newValue );
 }
}


438 名前:436 :2006/07/31(月) 19:28:44
例えば、

char array_1[] = "ちんこ", array_2[] = "まんこ", array_3[] ="アナル";

for (k = 1; k < 4; k++)
cout << array_k << endl;

とやっても、array_kを表示することをk=1〜3について繰り返すことになりませんよね。
こんな感じで、変数名・ファイル名だけ変えて同じ操作を繰り返したいんですが。。

439 名前:デフォルトの名無しさん :2006/07/31(月) 19:32:25
>>436
ファイル名はstd::stringstreamで生成する。
後は、わかるな?

440 名前:デフォルトの名無しさん :2006/07/31(月) 19:38:10
>>438
array_1は"array_1で"あって、数字部分は勝手に置き換えて考えられない。
k = 1 ・・・ n であろうと都合よく "array_k" みたく指定できないからね。
array[3][3]の2次元配列にすれば
for (int k = 1; k < 4; k++)
 for (int j = 1; j < 4; j++)
  cout << array[k][j] << endl;
で全要素を表示することならできる。
的外れだったらすまそ。

441 名前:デフォルトの名無しさん :2006/07/31(月) 19:38:54
std::list<int> c;

// ちょいと粋に1〜10までのコンテナを作る
c.push_back(1);
for(std::list<int>::iterator it = c.begin(), end = c.end(); it != end; ++it){
  int last = c.back();
  if(last<10) {
    c.push_back(last+1);
    if( end==c.end() )
      std::cout << "ニヤニヤ" << std::endl;
    else
      std::cout << "ごめんなさい" << std::endl;
  }
}
まーコンテナの種類によりけり

442 名前:デフォルトの名無しさん :2006/07/31(月) 19:40:07
>>437
std::listならそれもありかも……でもやりたいという場面が思いつかない。

443 名前:436 :2006/07/31(月) 19:42:56
>>439-441
有難うございます!
変数に関しては、2次元の配列にすれば行けそうですね。
ファイル名に関してはstd::っての使えばいいんですか・・・
stad::ってのを見たことが未だないんですが、そこら辺勉強してみます。

444 名前:デフォルトの名無しさん :2006/07/31(月) 19:46:21
>stad::ってのを見たことが未だないんですが
漏れもないな。

445 名前:デフォルトの名無しさん :2006/07/31(月) 19:56:25
>>437みたいな書き方したいときって結構ない?

446 名前:デフォルトの名無しさん :2006/07/31(月) 20:01:09
>443
ファイル名の生成は、別にCのsprintfでも良いけどな。

つか、いつになく初心者質問に優しいな。

447 名前:デフォルトの名無しさん :2006/07/31(月) 20:01:46
>>437
なぜ「まさか」なのかわからんが、iteratorを引数に取る、破壊的なメソッドが
コンテナには用意されてるだろ。
そのときはいちいちend()を実行する必要があるというだけの話しだ。

448 名前:デフォルトの名無しさん :2006/07/31(月) 20:08:30
>>442
なにかの条件でeraseするとか。
簡単な奴ならfor文じゃなくても書ける気がするけど、俺STLに詳しくないから知らない。

449 名前:デフォルトの名無しさん :2006/07/31(月) 20:09:45
OSタンとかいるならコンテナタンがいてもいいよなと思いつつある俺ガイル
最近はgoogle::sparse_hash_mapタンにぞっこん

450 名前:デフォルトの名無しさん :2006/07/31(月) 20:17:46
iteratorの実装をヘッダファイルで見てみりゃ、こんなアホなこと
いう奴減ると思う

451 名前:デフォルトの名無しさん :2006/07/31(月) 21:00:28
>>450
ヘッダファイルを自分で見て確認すること自体は俺もいいことだとは思うが、
それが規格で保証されていることと同列に扱われても困る。

452 名前:デフォルトの名無しさん :2006/07/31(月) 21:20:40
>>448
std::remove_if

しかし、std::listには専用のlist::remove_ifがあるし、
vectorとかには、ひとつずつeraseするより、remove_ifしたあとにresizeするほうが効率的だし……。

453 名前:デフォルトの名無しさん :2006/07/31(月) 21:34:00
remove→eraseじゃないの普通
そんな事してんの俺だけ?

454 名前:デフォルトの名無しさん :2006/07/31(月) 21:47:43
shrink to fit

455 名前:デフォルトの名無しさん :2006/07/31(月) 22:28:50
>>954
おっ
ER7035出たね
うちも出たんだがDVDインフォメーションセンターに問い合わせても分からず
工場だかに問い合わせてもらった結果、「普通は出ないはず」で
具体的な内容は客には伝えないことになってるって言われた
ひどい
(7000番台なのでHDD交換対応ではある)

456 名前:455 :2006/07/31(月) 22:31:09
誤爆スマソ

457 名前:デフォルトの名無しさん :2006/08/01(火) 21:13:58
ストリームへの浮動小数点でお聞きしたいことがあります。

3
1.5
10.4
4.88888

などを各行に一つずつ出力するときに、小数点の位置を
そろえて出力したいのです。

3.00000
1.50000
10.40000
4.88888

のように小数部にパディングが入っても構いません。
setw や setprecision ではうまくいかないのですが、
何か他に使えるマニピュレータなど有りますでしょうか?

458 名前:デフォルトの名無しさん :2006/08/01(火) 21:14:48
すみません、↑の書き込みですが、
先頭の空白が削られてしまいました。

459 名前:デフォルトの名無しさん :2006/08/01(火) 21:31:57
std::ios::showpoint で行けそうな気がしてきました。

460 名前:デフォルトの名無しさん :2006/08/01(火) 21:34:36
setwとsetprecisionで出来る

461 名前:デフォルトの名無しさん :2006/08/01(火) 22:13:55
C++の標準ストリームの勉強ついでにカスタマイズをしています
流れとしては
1 basic_streambufを継承・・クラスhoge_streambuf
2 basic_streambufのメンバ関数overflowをオーバーライド←ここでストリームに何か書く
3 basic_iostreamを継承・・・クラスhoge_stream
4 クラスhoge_streamにメンバとしてクラスhoge_streambufを持たせる
でとりあえず動いてはいるのですが、なぜ動いてるのか今いち理解できてません

overflowはバッファが溢れた時に呼ばれるらしい事まではわかったのですが・・・
この辺りについて詳しく解説しているサイト等あったら教えてください




462 名前:デフォルトの名無しさん :2006/08/01(火) 23:08:23
今まではCで書いていたのですが、最近C++に移行する必要が出てきました。
そこでC++でコードを書いてみたのですが、Cでほぼ同じものを書いた場合に比べて
実行速度が1/10くらいになってしまいました。

この現象について、何か心当たりのある方はいらっしゃいませんか?
中身のコードはほぼ一緒で、クラスを使ってみたという程度です。

アバウトな説明でもうしわけありません。

463 名前:デフォルトの名無しさん :2006/08/01(火) 23:12:53
>>462
まあ普通に考えれば、ほぼ同じものを書いたつもりで、そうではなかったということじゃないかな。
「一時オブジェクト」できまくりなコードを書いてしまったとか。

実コードを晒せば、誰かがアドバイスしてくれるかもよ。

464 名前:デフォルトの名無しさん :2006/08/01(火) 23:13:04
>>462
コンパイラがちがうから

465 名前:hehe :2006/08/01(火) 23:28:49
こんなクラスを書いた。

byte ClipToByte(int n)
{
    if (n < 0) n = 0;
    else if (n > 255) n = 255;
    return byte(n);
}

class ColorRGB {
private:
    byte _r, _g, _b;
public:
    // コンストラクタなどは省略
    int R(void) const { return _r; }
    int G(void) const { return _g; }
    int B(void) const { return _b; }
    int R(int r) { _r = ClipToByte(r); }
    int G(int g) { _g = ClipToByte(g); }
    int B(int b) { _b = ClipToByte(b); }
}


466 名前:hehe :2006/08/01(火) 23:29:46

これを使うと、
color.R( color.G() + color.B() );
のように書ける。

しかし、できれば、演算結果を次のように代入したい。
color.R() = color.G() + color.B();
こっちのほうが読みやすいし、書きやすい。

内部的には byte で保持しているので、次のようにはできない。
class ColorRGB {
public:
    int& R(void) { return _r; }
}


467 名前:hehe :2006/08/01(火) 23:31:32
上記の記法をサポートするために、カラーの要素を読み書きするための
プロキシ クラスを書いた。

class Color {
private:
    byte    _r;
    byte    _g;
    byte    _b;
public:
    // コンストラクタとかは省略

    class ConstRProxy {
    private:
        const Color* _color;
        void operator=(const ConstRProxy& lhs);
    public:
        ConstRProxy(const Color* color) : _color(color) {}
        ConstRProxy(ConstRProxy& lhs) : _color(lhs._color) {}
        operator int() const { return _color->_r; }
    };


468 名前:hehe :2006/08/01(火) 23:32:50
    class RProxy {
    private:
        Color* _color;
        void operator=(const RProxy& lhs);
    public:
        RProxy(Color* color) : _color(color) {}
        RProxy(RProxy& lhs) : _color(lhs._color) {}
        operator int() const { return _color->_r; }
        int operator=(int r) { return _color->_r = ClipToByte(r); }
    };

    ConstRProxy R(void) const { return ConstRProxy(this); }
    // ConstGProxy G(void) const { return ConstGProxy(this); }
    // ConstBProxy B(void) const { return ConstBProxy(this); }

    RProxy R(void) { return RProxy(this); }
    // GProxy G(void) { return GProxy(this); }
    // BProxy B(void) { return BProxy(this); }
};


469 名前:hehe :2006/08/01(火) 23:34:19
このようにすると、次のような記述ができる。
Color color(10, 20, 30;
byte r = color.R();
color.R() = color.G() + color.B();

しかし、この記法をサポートするためだけに、
こんなややこしいことをするのは、どうだろうか、と思う。
ご意見求む。

470 名前:デフォルトの名無しさん :2006/08/01(火) 23:40:43
C++にはプロパティという概念が無いから、いちいちプロパティっぽいものを
実装すると、混沌とした状況に陥ると思う。

471 名前:デフォルトの名無しさん :2006/08/01(火) 23:44:27
byte& R() {return _r;}のようにbyte&型を返すことにしてはではだめか?
byteという内部実装を曝け出してしまうが、そこはトレードオフと言うことで勘弁。
そこはbyteをそのまま曝け出すのではなく、Colorのメンバとしてpublicにtypedefするということで我慢しろ。

また、プロキシを書くならもっと完璧を目指せ。
operator =はきちんと*thisを返すべき。複合代入演算子やインクリメント・デクリメントも当然設けろ。
その例では、メンバ関数へのconst修飾をきちんとすれば、ConstRproxyとRProxyに分ける必要は無いはず。
クラステンプレートを使えば、RGBのプロキシをまとめて書けるはず。

472 名前:デフォルトの名無しさん :2006/08/01(火) 23:45:27
>>469 struct Color { byte r, g, b; };

473 名前:hehe :2006/08/01(火) 23:50:53
>> 471, 472
要点は、byte 型の演算後に値をラウンドするのではなく、
自動的にクリップしたいということなんです。

足りないメンバ関数があったり、不完全な実装があるのは承知しています。
そこは本題ではないので、無視していただけると幸いです。

474 名前:hehe :2006/08/01(火) 23:52:22

> メンバ関数へのconst修飾をきちんとすれば、ConstRproxyとRProxyに分ける必要は無いはず。

コンストラクタに const Color* を渡すか、Color* を渡すかを
切り替えないといけないので分けてあります。

> クラステンプレートを使えば、RGBのプロキシをまとめて書けるはず。

こちらはそのとおりですね。

475 名前:デフォルトの名無しさん :2006/08/02(水) 00:12:09
>>473
class ClippedByte
{
public:
ClippedByte(int n) : clipped(ClipToByte(n)) {}
operator int () const { return clipped; }
private:
byte clipped;
};
struct Color { ClippedByte r, g, b; };

476 名前:デフォルトの名無しさん :2006/08/02(水) 00:26:58
>>463-464
ありがとうございます!
参考に色々しらべてみたのですが、

>まあ普通に考えれば、ほぼ同じものを書いたつもりで、そうではなかったということじゃないかな。

が正解だったみたいです・・・お手数お掛けしました・・・。


ところで、一応速度的には向上したのですが、やはり遅いのは変わりません。
これは仕様ですか??

477 名前:デフォルトの名無しさん :2006/08/02(水) 00:39:01
知らん。
君がどういうコードを書いているのかわからんし。

478 名前:デフォルトの名無しさん :2006/08/02(水) 01:08:46
struct {
struct {
  int a, b, c;
} aaa[4];
} bbb;

たとえばある構造体のメンバが別の構造体の配列(ここでは4つ)だけの場合でも、
上のように書かないといけないのでしょうか?
それとも他のやりかたがあるんでしょうか。

479 名前:デフォルトの名無しさん :2006/08/02(水) 01:17:46
struct {
  int a, b, c;
} aaa[4];
でいいじゃん。

480 名前:デフォルトの名無しさん :2006/08/02(水) 01:29:01
>>479
bbbが配列となった時のことを考えておりまして、
例えば bbb[2].aaa[1].a = 0;
のようにしようかと思ってたのですが、やはりおかしいですかね?
普通に二次元配列にして aaa[2][1].a = 0; とかでいいんでしょうか。
それとも使い方によるのですかね?

481 名前:デフォルトの名無しさん :2006/08/02(水) 01:36:03
>>480
どっちでもいい。好きにしろ。何が聞きたいのかわからん。

482 名前:デフォルトの名無しさん :2006/08/02(水) 02:19:20
亀レスだが、

lib.list.modifiers insert()
Does not affect the validity of iterators and references.(略)

lib.associative.reqmts 8
The insert members shall not affect the validity of iterators and
reference to the container(略)


483 名前:デフォルトの名無しさん :2006/08/02(水) 02:41:30
static変数を同一名で親・子クラス内でともに宣言して、
メンバ関数(親クラスで定義したもの)でその変数を扱う場合
例)CSuperClass.func(){ static_value = 0; }
このメンバ関数を使うオブジェクトが親か子かによって
例でいうstatic_valueも親のもの、子のものにちゃんと振り分けられるのでしょうか
それとも親クラスで宣言した関数内だから親のstatic_valueが使われるのかな

484 名前:483 :2006/08/02(水) 02:42:58
↑間違えました
×CSuperClass.func()
○CSuperClass::func()

485 名前:デフォルトの名無しさん :2006/08/02(水) 02:58:19
>>483
「それとも」の方。

486 名前:483 :2006/08/02(水) 02:59:49
>>485
なるほど・・・静的変数はクラスの恩恵はあまり受けられないってことですね

487 名前:デフォルトの名無しさん :2006/08/02(水) 03:09:35
>486
恩恵とか意味が分からん。
子クラスに同じコードをコピペでもすれば?

488 名前:483 :2006/08/02(水) 03:21:22
>>487
まったく同じ関数なのに、static変数を扱うせいで別に用意しなきゃならないのは
クラス継承のメリットの一部分を生かせないと思いまして
まあstatic変数とはそういうものだということは承知してますが

489 名前:デフォルトの名無しさん :2006/08/02(水) 03:27:33
>>483
おそらく継承関係になってるのが設計ミスで
テンプレート+部分特殊化すべきクラスとみた

490 名前:デフォルトの名無しさん :2006/08/02(水) 04:03:32
メンバ変数にすりゃいいじゃんと思ったのは俺だけ?

491 名前:デフォルトの名無しさん :2006/08/02(水) 16:46:23
>>461
http://www.cc.nao.ac.jp/fsunman/japanese/C++/stdlib/stdug/loc_io/index.htm

492 名前:デフォルトの名無しさん :2006/08/02(水) 19:44:37
-1ってリテラルだっけ?
それともリテラルの1に単項演算子の-がついてるの?

493 名前:デフォルトの名無しさん :2006/08/02(水) 19:57:16
2.1.3.1 Integer literals [lex.icon] に符号はない。

494 名前:デフォルトの名無しさん :2006/08/02(水) 19:59:06
2.1.3.3 Floating literals [lex.fon] には符号があるな。

495 名前:デフォルトの名無しさん :2006/08/02(水) 20:39:27
>>493
どうも。
>>494
指数部だな。

496 名前:デフォルトの名無しさん :2006/08/02(水) 22:55:00
C++でJavaのDIみたいなことができるライブラリみたいなものってありますか?

497 名前:デフォルトの名無しさん :2006/08/03(木) 00:54:46
int a = 0xffffffffu;
でaの値は処理系依存ですか?(intが32bitのとき)

498 名前:デフォルトの名無しさん :2006/08/03(木) 01:05:13
>>496
COMとかXCOM

499 名前:デフォルトの名無しさん :2006/08/03(木) 02:43:54
>>497
4.7.3 より、整数から符号付整数への変換で、元の値が変換先の型で
表現できなければ、その値は処理系定義となる。

500 名前:デフォルトの名無しさん :2006/08/03(木) 03:28:10
//vect.h
template <class T>
class vect{
T coord[3];
public:
vect operator+(const vect &back)const;
};

//vect.cpp
#include "vect.h"
template <class T>
vect<T> vect<T>::operator+(const vect<T> &back)const{
・・・
}

という風に書き、main関数内でdouble型のインスタンスを二つ生成し、そのインスタンス同士を足して
オペレーターを呼ぶようなソースを書くと、リンカが
error LNK2019: 未解決の外部シンボル
"public: class vect<double> __thiscall vect<double>::operator+(class vect<double> const &)const " (??H?$vector3d@N@@QBE?AV0@ABV0@@Z) が関数 _main で参照されました。
というエラーが出て実行できません
コンパイルしたときはエラーも何もなく、どうしたらいいのかわからなくて困っています
なにが原因だかわかりますでしょうか?


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