[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 2chのread.cgiへ]
Update time : 03/13 15:15 / Filesize : 207 KB / Number-of Response : 692
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

Boost総合スレ part7



1 名前:デフォルトの名無しさん [2009/01/19(月) 21:22:22 ]
過去スレ
part 6 pc11.2ch.net/test/read.cgi/tech/1207749841/
part 5 pc11.2ch.net/test/read.cgi/tech/1192662575/
part 4 pc11.2ch.net/test/read.cgi/tech/1175663346/
part 3 pc11.2ch.net/test/read.cgi/tech/1158991211/
part 2 pc8.2ch.net/test/read.cgi/tech/1139313234/
part 1 pc8.2ch.net/test/read.cgi/tech/1091198276/

■関連サイト■
Boost C++ Libraries
www.boost.org/

Boost 翻訳プロジェクト
boost.cppll.jp/HEAD/

Let's Boost
www.kmonos.net/alang/boost/

boost info
shinh.skr.jp/boost/

321 名前:315 mailto:sage [2009/04/10(金) 20:58:38 ]
>>319
ありがとうございます。
警告レベルを/W3から/W4へ引き上げたら、「代入演算子が生成できない」という警告が出ました。
警告の内容はよく分からないんですが、やっぱり型がおかしかったみたいです。


// Release設定でコンパイルしたら何故か正常に計算されて笑いましたけど。


322 名前:デフォルトの名無しさん mailto:sage [2009/04/10(金) 21:22:27 ]
>>321
ReleaseとDebugどちらか片方でのみ正常に動作する場合、
参照先が「初期化されていない」か「既に解体されている」ことが多い。

315は「+=」で生成されるオブジェクトが0.5をconst参照で保持しているのが問題。
0.5は一時変数なので、funcの初期化が完了した時点で解体される。
「=」が正常に動作するのは、10.0をコピーして保持しているため。
constant(0.5)も同様。

323 名前:デフォルトの名無しさん [2009/04/12(日) 16:25:57 ]
typedef boost::mpl::vector<int, char, std::string> vector;
typedef boost::mpl::if_c<boost::is_pod<boost::mpl::_1>::type::value,
boost::add_pointer<boost::mpl::_1>::type,
boost::mpl::_1,
> operate;
typedef boost::mpl::transform<vector, operate>::type result;

mpl::transform の Op に mpl::if_c は使えないの?

324 名前:デフォルトの名無しさん mailto:sage [2009/04/12(日) 19:59:48 ]
そもそも使い方がめちゃくちゃなんだが何がしたいんだ。

325 名前:デフォルトの名無しさん [2009/04/12(日) 20:22:51 ]
typedef boost::mpl::vector<int, char, std::string> vector;
typedef boost::mpl::if_<boost::is_pod<boost::mpl::_>, boost::add_pointer<boost::mpl::_> ,boost::mpl::_> operate;
typedef boost::mpl::transform<vector, operate>::type result;
を、if_cに書き換えたんだけど・・・
typedef boost::mpl::vector<int, char, std::string> vector;
typedef boost::mpl::if_c<boost::is_pod<boost::mpl::_>::type::value, boost::add_pointer<boost::mpl::_>::type, boost::mpl::_> operate;
typedef boost::mpl::transform<vector, operate>::type result;

typedef boost::mpl::transform・・・の行をコメントアウトすればコンパイルは通る。

めちゃくちゃってどこが?



326 名前:デフォルトの名無しさん mailto:sage [2009/04/12(日) 20:53:39 ]
using namespace boost::mpl::placeholders ;
typedef boost::mpl::if_< boost::is_pod< _1 >, boost::add_pointer< _1 >, _1 > operate ;

これで通るはず。
そもそもな、lambda expressionは、その時に評価してもしょうがないだろ。
add_pointer<_1>::type とした時点で、メタ関数は評価されているんだ。
transformの中で評価させたいんだから、早漏はコンパイラに嫌われるぞ。

>>325
そりゃ当たり前だ。transformに通さなきゃコンパイルは通るだろ。
こんどはunaryですらなくなってるぞ。



327 名前:デフォルトの名無しさん mailto:sage [2009/04/12(日) 20:56:32 ]
struct print_type
{
template < typename T >
void operator () (T) const
{
std::cout << typeid(T).name() << std::endl ;
}
} ;


int main()
{
using namespace boost::mpl::placeholders ;

typedef boost::mpl::vector< int, char, std::string > vector;
typedef boost::mpl::if_< boost::is_pod< _1 >, boost::add_pointer< _1 >, _1 > operate ;
typedef boost::mpl::transform< vector, operate >::type result ;

boost::mpl::for_each< result >( print_type() ) ;
}

動いてるみたいだな。

328 名前:325 [2009/04/12(日) 21:11:53 ]
>>326
>typedef boost::mpl::if_< boost::is_pod< _1 >, boost::add_pointer< _1 >, _1 > operate ;

なら期待した動作することは確認済みです。
if_c でやりたい。

329 名前:325 [2009/04/12(日) 21:12:37 ]
>>327
>>328




330 名前:デフォルトの名無しさん mailto:sage [2009/04/12(日) 21:19:32 ]
それは無理というものだ。
なぜなら、if_cは、メタ関数ではなく、boolを要求するんだから。
lambda expressionにしようがない。すぐに評価されては困るんだよ。
boost::is_pod< _1 >::type:value と、ネストされた型や定数を見た時点で、すでにinstantiateされる、つまり評価されているんだ。

331 名前:デフォルトの名無しさん mailto:sage [2009/04/15(水) 15:21:46 ]
javaの拡張scalaの上をいくものはできないものかなあ

332 名前:デフォルトの名無しさん mailto:sage [2009/04/15(水) 16:57:44 ]
>>331
Scalaのどの機能が欲しいの?おせーてプリーズ。

333 名前:デフォルトの名無しさん mailto:sage [2009/04/16(木) 17:57:49 ]
boost::unit_test_frameworkについて質問です。

今、std::wstring ToWide(std::string& rhs) という関数があり
この関数をテストするために
  std::wstring ans = L"テスト";
  std::string str = "テスト";
  BOOST_CHECK_EQUAL( ToWide(str), ans );
というケースを書きましたが、コンパイルエラーになってしまいます。
  BOOST_CHECK( ToWide(str) == ans );
とは書けましたのでwchar_tが出力されるときはこっちにすればいいのですが
wstringを出力できるようにするにはどうすればいいのでしょうか。

最近boostを使い始めたので変なこといってたらごめんなさい。

334 名前:デフォルトの名無しさん mailto:sage [2009/04/16(木) 18:53:18 ]
boost.lambdaから関数オブジェクト作ろうとすると
とんでもないタイプ量必要なのなんとかなんないの

335 名前:デフォルトの名無しさん mailto:sage [2009/04/16(木) 18:54:32 ]
C++03の限界です。あきらめてください。

336 名前:デフォルトの名無しさん mailto:sage [2009/04/17(金) 22:17:38 ]
更新しました。今週もドキュメントとビルドシステムの整備が多いです。
亦、boost_pythonのビルドをPython2.6.2ベースに移行しました。
ttp://booster.x0.to/
以下更新内容の一部
[Graph]
Merged in changes from Nick to distributed betweenness centrality
Merged in code and docs from Parallel BGL; CMake-based build system for tests and examples and docs is not working; src and doc can be built with bjam


[Mpl]
mpl::string is a bidirectional sequence, not random access; c_str is a separate metafunction, not a class static
fix off-by-1 errors
add and document BOOST_MPL_LIMIT_STRING_SIZE and mpl/limits/string.hpp
saving some additional template instantiations
[Math]
Add more instrumentation code, along with some AMD64/Linux fixes.
[Exeption]
fixing an error that caused warnings in diagnostic_information.hpp
[Signals2]
signals2/signal.hpp does not need to include signals2/shared_connection_block.hpp.
Fixed compile errors in c++0x mode.
[Interprocess]
Modified examples so that they can be run in parallel.
[Unordered]
Add stream output to the count test helper for unordered.
[Filesystem]
Fix #2948 - Path typedef moved to namespace boost::filesystem
Fix incompatibility between asio and ncurses.h due to the latter defining
a macro called "timeout". Fixes #2156.
[Program_options]
Sync trunk&release branches

337 名前:デフォルトの名無しさん mailto:sage [2009/04/17(金) 22:41:50 ]
>>336
乙!

338 名前:デフォルトの名無しさん mailto:sage [2009/04/18(土) 15:35:43 ]
配列の要素数を変更する予定がなく、
しかしコンテナとしての扱いをしたい。

こんな場合にはboost::arrayがあるらしいですが、
これはstd::vectorよりも効率(速度やバイナリのサイズなど)
が良いのでしょうか?
std::vectorは標準ですからboost::arrayよりも
最適化の研究が(VC++やg++など有名どころで)なされているとか
そういったことは普通ないですよね?




339 名前:デフォルトの名無しさん mailto:sage [2009/04/18(土) 15:41:09 ]
以前実測したときはvectorよりは多少効率が良い程度だったよ。
当然ながらarrayでも生配列に比べるとかなり効率悪かった。



340 名前:デフォルトの名無しさん mailto:sage [2009/04/18(土) 15:46:08 ]
自分の環境で実測するしかないんじゃない

341 名前:338 mailto:sage [2009/04/18(土) 15:55:59 ]
>>339
ありがとうございます。
ご教示に従い、コンパイル時に数が決まっている状況では
生配列にすることも考えてみます。

>>340
やっぱそうですよね。
そもそも本当にそれがボトルネックになっているのかから考えないといけませんしね。。。


342 名前:デフォルトの名無しさん mailto:sage [2009/04/18(土) 17:03:54 ]
>>339
最適化したのか?
vectorをreserveせずに増やしまくりとかじゃなければ、
配列だろうとarrayだろうと大した差はないと思うけど

343 名前:デフォルトの名無しさん mailto:sage [2009/04/18(土) 19:25:06 ]
>>342
たしかに大差ないんだが、indexでのアクセスはやっぱ生より遅い。

344 名前:デフォルトの名無しさん mailto:sage [2009/04/18(土) 19:42:39 ]
>>343
つまりは
実行スピードは
std::vector > boost::array >> 生の配列
か。

345 名前:デフォルトの名無しさん mailto:sage [2009/04/18(土) 19:44:31 ]
それ実行時間w

346 名前:デフォルトの名無しさん mailto:sage [2009/04/18(土) 19:54:37 ]
>>345
アウチ!
間違ったw

347 名前:デフォルトの名無しさん [2009/04/18(土) 21:29:19 ]
vectorと、固定長配列の違いは、動的かそうでないかだけでは。
vectorだと多く確保できるけど、HDDに移される可能性がありそれが速度低下の原因では

348 名前:デフォルトの名無しさん mailto:sage [2009/04/18(土) 21:37:16 ]
環境依存の原因なんか挙げ始めればきりがない。
理論的には O(1) で同じと考えられる。

349 名前:338 mailto:sage [2009/04/18(土) 21:43:22 ]
>>342-348
なるほど。
みなさま貴重なご意見ありがとうございます。



350 名前:デフォルトの名無しさん mailto:sage [2009/04/18(土) 21:44:05 ]
オーダーの話されてもなぁ。
ハッシュだって理屈の上ではO(1)だぜ?


351 名前:デフォルトの名無しさん mailto:sage [2009/04/18(土) 21:51:09 ]
>>350 で、何の話がしたいの?

352 名前:デフォルトの名無しさん mailto:sage [2009/04/19(日) 01:58:00 ]
>>347
固定長配列は、(自動変数なら)スタックポインタを減算するだけで確保できる。
それと比べれば、ヒープから空きメモリを探してくるvectorというかnew[]は確保に時間がかかる。

その点ではboost::arrayが組込の配列と比べて遅くなる要素は無いはずなんだけど。
(もちろん最適化がしっかりしていて、アサート全OFFという前提のもと)

353 名前:デフォルトの名無しさん mailto:sage [2009/04/19(日) 03:27:48 ]
> std::vector > boost::array >> 生の配列
なんか激しく疑わしいので比べてみた。@i386 gcc 4.1.2 -O2

for (size_t i = 0; i < size; ++i) cout << v[i] << endl;

生配列
.L21:
movl (%edi,%ebx,4), %eax
addl $1, %ebx
movl $_ZSt4cout, (%esp)
movl %eax, 4(%esp)
call _ZNSolsEi
movl %eax, (%esp)
call _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
cmpl %esi, %ebx
jne .L21
vector
.L15:
movl (%edi), %eax
movl (%eax,%ebx,4), %eax
addl $1, %ebx
movl $_ZSt4cout, (%esp)
movl %eax, 4(%esp)
call _ZNSolsEi
movl %eax, (%esp)
call _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
cmpl %esi, %ebx
jne .L15

まあ、確かに遅くはなると思うが・・・

354 名前:デフォルトの名無しさん mailto:sage [2009/04/19(日) 12:48:08 ]
movl 2回で済むところが3回になるのだから、そこだけみると結構遅いだろ?

355 名前:デフォルトの名無しさん mailto:sage [2009/04/19(日) 13:06:42 ]
movl (%edi), %eax
movl (%eax,%ebx,4), %eax

すごく無意味なことしてる気がするんだけど気のせい?
なんでこんなことしてるんだろ?


356 名前:デフォルトの名無しさん mailto:sage [2009/04/19(日) 13:25:25 ]
たまたま反復文の中が1行だったから比較的コストが高そうに見えるけど、
普通はそうじゃないよな。
うちのPCで国家予算分のジャリ銭を数え上げたら数分差が出るかもしれないけどさ。
(それでも分岐予測ミスによる揺らぎよりは小さそう・・・)

結局ありきたりの結論だけど
vectorが遅いかもしれないから生配列を使うことを検討するのに時間を使う方が
よっぽどコスト高だな。
int* vv = &v[0];
for (size_t i = 0; i < size; ++i) { cout << vv[i] << endl; }
とかすれば生配列と全く同じ速度になるわけだし。

357 名前:デフォルトの名無しさん [2009/04/19(日) 13:33:27 ]
確保される場所が違うだろ。
スタック上ではHDDにはうつりにくいけど
動的確保したらうつりやすい

358 名前:デフォルトの名無しさん mailto:sage [2009/04/19(日) 13:52:46 ]
>355
vector から先頭アドレスをロード。
要素の内容をロード。
だから無意味だとは思わないが、なんで?
毎回先頭アドレスをロードするのが無駄ってこと?

359 名前:デフォルトの名無しさん mailto:sage [2009/04/19(日) 14:39:29 ]
>>357
それは生配列かどうかとは違う問題では?

そもそも速度の変化を検知できるほど大きな配列をスタックに配置したら
数ページまるまる配列データだけになったりして、
そのページにアクセスする確率(≒スワップされない確率)は
ヒープ領域と変わらなくなってしまうんじゃないか?

ていうかメモリ増やせ。



360 名前:デフォルトの名無しさん mailto:sage [2009/04/19(日) 17:51:13 ]
うん、まぁほとんどの場合、生かvectorかで差がでることは
メモリの再配列以外では無いのは確かなんだ。
でも1.5倍以上の差がでる可能性があるのも間違いないからね。
どちらにするか悩むのは無駄だが、知識として抑えておくのは
悪いことではないでしょう。

361 名前:デフォルトの名無しさん mailto:sage [2009/04/19(日) 18:39:44 ]
>>358
生配列みたく
movl (%edi,%ebx,4), %eax
の1行でいいんじゃないの?ってことじゃないかと。

362 名前:デフォルトの名無しさん mailto:sage [2009/04/19(日) 18:41:40 ]
>>361
まぁそうだとしたら

>>355
は、レジスタの値とレジスタの値が指す先を混同してるってことか



363 名前:338 mailto:sage [2009/04/19(日) 22:55:36 ]
ええと、皆様ありがとうございます。

アセンブラは全然理解出来ていないのですが、
頑張ってよく読ませていただきます。

364 名前:デフォルトの名無しさん mailto:sage [2009/04/20(月) 00:21:29 ]
>1.5倍以上の差がでる可能性があるのも間違いない
どこからそんな結論が

365 名前:デフォルトの名無しさん mailto:sage [2009/04/20(月) 00:57:25 ]
>>360
まず、お前がもっと深い知識を蓄えてから発言しろ

366 名前:デフォルトの名無しさん mailto:sage [2009/04/20(月) 06:23:45 ]
相手にも言えるレスで相手を馬鹿にしても、効果は薄いし説得力にも欠ける。

367 名前:デフォルトの名無しさん mailto:sage [2009/04/20(月) 09:28:05 ]
shared_ptrって参照数を保持する変数をnewしてるんだよね。てことは、
shared_ptr<int> pn(new int(0));
とか書くと、intはnewできてコンストラクタ内でnewが例外投げるとintのポインタが行方不明になる?

うん、なるな。

368 名前:デフォルトの名無しさん mailto:sage [2009/04/20(月) 09:35:15 ]
>>367
なんでドキュメントを読まずに「行方不明」とか意味のわからない結論で納得するの?
www.boost.org/libs/smart_ptr/shared_ptr.htm#constructors
> Exception safety: If an exception is thrown, delete p is called.

369 名前:367 mailto:sage [2009/04/20(月) 09:46:13 ]
うん、ヘッダ見たらすぐにわかった。恥ずかしい。



370 名前:デフォルトの名無しさん mailto:sage [2009/04/20(月) 11:15:45 ]
>>344
352も言ってるけど、何で生配列とboost::arrayで差が出るんだよ
353のループ部を gcc 4.3.3 -O2 で試したけど、まったく同じアセンブラコードになったぞ

371 名前:デフォルトの名無しさん mailto:sage [2009/04/20(月) 11:38:09 ]
お前の世界にはgccしかないのか?

372 名前:デフォルトの名無しさん mailto:sage [2009/04/20(月) 11:50:44 ]
お前はgccよりひどい最適化のコンパイラを使うのか?

373 名前:デフォルトの名無しさん mailto:sage [2009/04/20(月) 11:51:38 ]
multiarrayの方だけど

> boost::array<array_type::index,3> idx = {{0,0,0}};
> A(idx) = 3.14;
>この方法は次元非依存のコードを書くのに役立ち,
>いくつかのコンパイラの下では operator[] よりも高いパフォーマンスをもたらす。

とboost.cppll.jpに解説があるくらいなので、オーバーライドされた[]が最適化
されないケースは間違いなくあるんだろう。

374 名前:デフォルトの名無しさん mailto:sage [2009/04/20(月) 11:57:18 ]
だな

375 名前:デフォルトの名無しさん mailto:sage [2009/04/20(月) 12:02:56 ]
つまり、boost::arrayで速度が問題になるようならより最適化されやすいA(idx)を使えばいいってこと?

376 名前:デフォルトの名無しさん mailto:sage [2009/04/20(月) 13:43:59 ]
370の言ってることが間違いじゃなければgccなら最適化されるから
速度が問題になることはないだろう。
つまりgcc使えば良いんだよ。
ターゲット環境にgccが無いのなら、移植しろってことなんだろう。

377 名前:デフォルトの名無しさん mailto:sage [2009/04/20(月) 21:04:20 ]
>>375
multiarrayのoperator []が遅くなる要因は一時オブジェクトを作らないといけないからだと思う。

ところで、VC++ 9でも試してみたけど、やっぱりboost::arrayと生配列で出て来るコードは同じだった。
NDEBUGを定義して/O2で。
まあ普通のコンパイラならこれくらいGCCでなくても当然だと思う。

378 名前:デフォルトの名無しさん mailto:sage [2009/04/20(月) 21:12:30 ]
最適化に関するたいした知識のない俺から見れば
g++やVC++の最適化機能ってすんげーんだな
と思う。

だって俺、最適化機能のあるコンパイラを作れって
言われても絶対無理だと思う。
そんな「boost::arrayと生配列で出て来るコードは同じ」みたいな
ところまで気を回せるコンパイラの作者陣って
ホントに尊敬するわ。

379 名前:デフォルトの名無しさん mailto:sage [2009/04/20(月) 21:26:02 ]
boost::arrayのコードを見れば
ごく当たり前のことなんだけどな



380 名前:デフォルトの名無しさん mailto:sage [2009/04/20(月) 21:51:47 ]
inline展開様々だな

381 名前:デフォルトの名無しさん mailto:sage [2009/04/21(火) 03:43:59 ]
だな

382 名前:デフォルトの名無しさん mailto:sage [2009/04/21(火) 22:39:48 ]
boost::shared_ptr<MyClass> ptr;

これを関数に渡す場合、const参照渡しにした方が望ましいの?

それとも
STLのイテレータや組み込み型変数のようにconst参照渡しよりコピー渡しの方が望ましいの?

383 名前:デフォルトの名無しさん mailto:sage [2009/04/21(火) 23:01:47 ]
普通に値渡しの方がいいんじゃない?
どうせそこまで速度稼ぎたいわけじゃないだろうし、ポインタと同じように扱うためのスマートポインタだし。

384 名前:デフォルトの名無しさん mailto:sage [2009/04/21(火) 23:25:38 ]
値渡しじゃないと参照カウント増えないんじゃないか?

385 名前:デフォルトの名無しさん mailto:sage [2009/04/22(水) 00:19:58 ]
>>384
関数内で、別の変数に代入するなどすれば、そのとき増えるので無問題。

それとは別の話で、もしptrの参照先を見るだけだったら、
ただのMyClass&/MyClass const&にすればいいな。


386 名前:デフォルトの名無しさん mailto:sage [2009/04/22(水) 00:42:04 ]
const参照にしとけ。

使ってる場所が多いと、値だと結構クルよ。

387 名前:デフォルトの名無しさん mailto:sage [2009/04/22(水) 01:19:29 ]
呼び出し元次第。
const参照だと、実際に使うときに実体が存在しない危険がある。

388 名前:デフォルトの名無しさん mailto:sage [2009/04/22(水) 06:13:57 ]
>const参照だと、実際に使うときに実体が存在しない危険がある。
呼び出し元にはshared_ptrがあるのだから、関数実行中に実体が消えることはないと思うんだけど。

389 名前:デフォルトの名無しさん mailto:sage [2009/04/22(水) 13:11:54 ]
>>388
その理屈だとshared_ptr自体いらなくね?



390 名前:デフォルトの名無しさん mailto:sage [2009/04/22(水) 16:12:07 ]
オブジェクトの寿命を自分で管理したいのか、shared_ptrに管理させたいのかで決めれば良いと思う

391 名前:デフォルトの名無しさん mailto:sage [2009/04/22(水) 20:51:14 ]
>>389
なんで?そんな理屈にはならんよ。

392 名前:デフォルトの名無しさん mailto:sage [2009/04/22(水) 20:53:38 ]
>>391
auto_ptrで充分じゃね?

393 名前:デフォルトの名無しさん mailto:sage [2009/04/22(水) 20:57:57 ]
>>392
だからなんでそんなことになるの?

394 名前:デフォルトの名無しさん mailto:sage [2009/04/22(水) 21:01:08 ]
>>392
auto_ptrは使用禁止でもおかしくない。

395 名前:デフォルトの名無しさん mailto:sage [2009/04/22(水) 21:12:12 ]
#define auto_ptr unique_ptr

396 名前:デフォルトの名無しさん mailto:sage [2009/04/22(水) 21:37:41 ]
>>392
おいおい素人にも程があるだろ・・・

397 名前:382 mailto:sage [2009/04/22(水) 22:19:38 ]
ふーむ、なるほどね。
そういったことを考えて決定するのが正しいのね。
ありがとう。

398 名前:デフォルトの名無しさん mailto:sage [2009/04/22(水) 22:46:44 ]
引数は何も考えずconst参照にしといて問題ない

399 名前:デフォルトの名無しさん mailto:sage [2009/04/22(水) 23:10:09 ]
組み込み型は値渡しがいいなあ



400 名前:デフォルトの名無しさん mailto:sage [2009/04/22(水) 23:43:04 ]
>>398
組み込み型とイテレータは値渡しが望ましいとEffective C++で書かれていた気がするんだが。

401 名前:デフォルトの名無しさん mailto:sage [2009/04/23(木) 00:11:10 ]
今はshared_ptrの話をしてるんじゃないのか

402 名前:デフォルトの名無しさん mailto:sage [2009/04/23(木) 00:40:38 ]
>388
それはshared_ptrのオーナー次第。関数自体はオーナーじゃ無いことに注意する必要がある。
下記はかなり恣意的な例だけど、マルチスレッドプログラムだとすぐ嵌りそうですな。


struct A {
A() : s(new std::string) {};
boost::shared_ptr<string> s;
}

void doom(std::auto_ptr<A> body, boost::shared_ptr<string>& str) {
*str; // boo!!
};

int main() {
std::auto_ptr<A> a(new A);
doom(a, a->s);

}



403 名前:デフォルトの名無しさん mailto:sage [2009/04/23(木) 01:04:44 ]
>>402
この例が一体何を示しているというのか。

boo!とか書いてるところで何か起きるわけでもなし。

404 名前:デフォルトの名無しさん mailto:sage [2009/04/23(木) 01:26:28 ]
>>402
それ問題ないです…
マルチスレッドについてはconst参照でなく値渡ししたとしても、
コピー操作がアトミックじゃない以上は嵌る可能性があるよ。

shared_ptrの実装自体がconst参照使ってるわけだし、基本はconst参照でいいと思う。

405 名前:402 mailto:sage [2009/04/23(木) 02:11:38 ]
本当?>404
死んでるshared_ptrの参照剥しをしているんだけど?

まあ、マルチスレッドについてはアトミックなカウンタじゃないと死ぬっつうのは確かですな。
C++0xでマルチスレッド対応するらしいけど……

406 名前:デフォルトの名無しさん mailto:sage [2009/04/23(木) 02:14:31 ]
>>405
お前、実行してみろ。本当?じゃねーよ。

407 名前:デフォルトの名無しさん mailto:sage [2009/04/23(木) 02:19:37 ]
>>405
doom() を抜けるまでは最初の new A で生成したインスタンスは生きてるように見えるが?

408 名前:402 mailto:sage [2009/04/23(木) 02:53:07 ]
あ、本当だ。ごめん。こうしないと死なないね。
まあ、マルチスレッドでもなきゃやらんだろうけど。

struct A {
A() : s(new std::string) {};
boost::shared_ptr<string> s;
}
void doom(std::auto_ptr<A> body, boost::shared_ptr<string>& str) {
{
std::auto_ptr<A> b(body);
}
*str; // boo!!
};
int main() {
std::auto_ptr<A> a(new A);
doom(a, a->s);
}

409 名前:デフォルトの名無しさん mailto:sage [2009/04/23(木) 02:59:58 ]
>>408
なんかもう shared_ptr も何も関係ないな。



410 名前:デフォルトの名無しさん mailto:sage [2009/04/23(木) 03:06:30 ]
>>408
>>402がまずいコードなのは確かだけど、*strの問題じゃないよ。
bodyが先に生成されればa->sの時点で死ぬ。
strが先に生成されれば問題なし。
そして引数の評価順は不定であり、評価順依存のコードの実行結果は未定義なので、
コード自体が間違っている。

411 名前:デフォルトの名無しさん mailto:sage [2009/04/23(木) 03:23:24 ]
>>410
a による body の初期化って、順番が不定な「引数の評価」に含まれるの?

5.2.2 Function call の p4 より
> When a function is called, each parameter shall be initialized with its corresponding argument.
同じく p8 より
> All side effects of argument expression evaluations take effect before the function is entered.

とか、読んでみたけどはっきりしない。

412 名前:デフォルトの名無しさん mailto:sage [2009/04/23(木) 07:40:17 ]
まあとにかく、shared_ptrは何も考えずconst参照にしといて問題ないよ。

413 名前:デフォルトの名無しさん mailto:sage [2009/04/23(木) 12:36:08 ]
>>411
5.2.2 p4のこれがそうなんじゃないかなあ。
>The initialization and destruction of each parameter occurs within the context of the calling function.

414 名前:382 mailto:sage [2009/04/23(木) 19:20:17 ]
ふーむ。
試しに
void foo(const boost::shared_ptr<MyClass> &p)
{
p->m_func();
}

void foo(boost::shared_ptr<MyClass> p)
{
p->m_func();
}
とだけが異なった2種のソースをg++に渡して-O2でコンパイルさせてみたら、
後者の方が大きかったんだが。

とりあえずこのソースに限り、ファイルサイズはconst参照じゃない方が小さく済むみたい。
実行時間は・・・どうやって調べればいいの?


415 名前:デフォルトの名無しさん mailto:sage [2009/04/23(木) 20:17:17 ]


416 名前:デフォルトの名無しさん mailto:sage [2009/04/23(木) 20:29:06 ]
>>414
とりあえずcodepadかどこかにソースうpしてもらえないとなんとも

417 名前:414 mailto:sage [2009/04/23(木) 20:41:45 ]
さすがにエスパー要求しすぎなレスだったね。
すまなかった


C++ code - 38 lines - codepad
ttp://codepad.org/xAdtSWJO
コピーバージョン。

C++ code - 38 lines - codepad
ttp://codepad.org/nNuvdFvf
const参照バージョン


このソースをg++に渡してコンパイラオプション-O2で
コンパイルさせてみたら、後者の方が大きかった。

となると、後者の方が効率が悪いってことかなぁ
→でも効率を論ずるならやっぱり速度を測定しないとなぁ
→速度の実測ってどうすればいいのか分からない

ってことです。m(_ _)m

418 名前:デフォルトの名無しさん mailto:sage [2009/04/23(木) 21:45:07 ]
それくらい自分で調べろ、っていうか速度気にするレベルじゃなくない?

419 名前:414 mailto:sage [2009/04/23(木) 23:18:17 ]
>>418
それもそうだな。
boostのtimerでも使うか。




420 名前:デフォルトの名無しさん mailto:sage [2009/04/23(木) 23:28:56 ]
const参照は不完全型が許されるのがいい。

421 名前:デフォルトの名無しさん mailto:sage [2009/04/24(金) 10:10:05 ]
デフォでconst参照でいいってぐらいconst T&ばっかりになるから困る






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<207KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef