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


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

【C++】STL(Standard Template Library)相談室 8



1 名前:858 [2007/12/24(月) 03:41:59 ]
C++標準ライブラリの一つ、STLについて。

前スレ
【C++】STL(Standard Template Library)相談室 7
pc11.2ch.net/test/read.cgi/tech/1185986999/

過去ログ・リンク・書籍紹介は >>2 以降

762 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 12:32:11 ]
イテレータについて質問です。
イテレータをインクリメントするコストはコンテナによって違うと思うのですが、
STL解説サイトなどで、そのことについて触れているのをみかけません。
速度を知りたければ、実装毎にテストして計るしかないのでしょうか?

763 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 13:08:30 ]
>>762
実際の速度(具体的な処理時間)を知りたいのならそれでいいんじゃね?
ソースやアセンブル結果を見て見当をつけても良いけど。


764 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 13:08:44 ]
VC++2005で、
std::map<std::string,int> mp;
mp["key000"]=0;
とすると、「stringに>演算子がない」ってエラーが出るんだが、これって標準C++準拠の正しいエラーなのかな?
それともVC++2005のstringの方がおかしいのかな?

ネットで検索した時に普通にstd::stringをキーにしてるソースあったんで、問題ない書き方だとは思うんだが。

765 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 13:13:37 ]
>>762
折角ソースがあるんだから読めばいいんじゃね?

766 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 13:18:50 ]
>>764
標準準拠である確信は無いけど、g++-4.2.3では普通に使えた

767 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 13:31:04 ]
>>764
VS2005でその二行を今書いているコードにペーストしてビルドしたけど、普通に通ったよ。

768 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 13:32:00 ]
>>764
エラーメッセージを変に略さずに、そのまま晒したり Google に放り込むと、
なにか余計なことをしているのが見つかるかもしれない。

769 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 13:38:22 ]
ヘッダincludeしてない時に出るメッセージに似てる…

770 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 13:38:42 ]
>>764 ヘッダのincludeが足りてないのでは?

#include "stdafx.h"
#include <map>
#include <string> ←これをコメントアウトすると、「stringに>演算子がない」ってエラーが出る

int _tmain(int argc, _TCHAR* argv[])
{
std::map<std::string,int> mp;
mp["key000"]=0;

return 0;
}



771 名前:764 mailto:sage [2008/02/19(火) 13:45:41 ]
早いレスd。
#include <string>が抜けてただけでした。
お騒がせして申し訳ないです。

772 名前:762 mailto:sage [2008/02/19(火) 14:07:09 ]
>>763,765
どうもです。
ソース見て見当つけるの難しいですね(if文のコストとポインタ代入のコストの比率がどのぐらいになるのかとかさっぱりです)。
c++の制御文や演算のコストについて、本などでほとんど目にしないのですが、皆さんはどうやって勉強されました?

773 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 14:20:26 ]
>>772
環境によって違うんだから、ある程度一般化せざるをえない本なんかで「勉強」するのは
無理だろ。

速度が要るプログラム組むときに、いろんなコードに対応するアセンブリを見て経験的に
身に付けるのがいいんじゃね?

環境が変われば結果が変わるということにも気をつけないといけない。

774 名前:762 mailto:sage [2008/02/19(火) 14:47:14 ]
>>773
なるほど。
経験的に身につけていくしかないですか。
速度見積もるのに技術がいる上、環境で変わることを考えると、
速度はあまり気にせず、プロファイリングしてからボトルネックとなっている部分だけ考えるのがいいんでしょうね。

775 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 14:55:08 ]
ばかすぎる

776 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 15:00:48 ]
自己卑下ですか?

777 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 16:31:26 ]
スパコンやx86-64のSSE2最適化の場合はvectorを使って、ベクトル化させたい場所はポインタに変換してる。
iteratorなんか使うと最適化してくれないし。

778 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 16:34:19 ]
>>772
まあ、こういう細かい部分を気にするのは悪いことじゃないよね。
でもそれはC++の勉強ではなくて、ターゲット環境のしくみを先に勉強した方が良いよ。
CPUがC++で作ったコードをどう処理するのか、とかさ。
昔みたいにクロック数を数えれば分かるような簡単な時代じゃないけど、
その疑問に答えるためには、結局そのあたりの知識が必要だから。


779 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 17:38:29 ]
スパコンでどんなソフト作ってんの?

780 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 17:59:00 ]
>>777
やっぱり、本物の数値演算には valarray は使い物になりませんか?



781 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 18:00:28 ]
下手にC++で書くよりMatlabで書いた方が早い

782 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 19:57:54 ]
>>774
理論的な計算量のオーダーだけは気にしておいた方がいい。
O(N^2)の処理をやっている場所やO(N)の処理を繰り返す場所があったら
適切なコンテナやアルゴリズムを選定することを考えるべき。
結果的にはmapやsetを使うよりvectorを毎回検索、ソートした方が
速いというケースはあるけど、チューニングする以前のエイヤッと決める段階では、
理論的に速いアルゴリズムを選んでおいた方が無難。

783 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 21:41:57 ]
>>780
つーか、C++自体が使い物にならなったりする。
ヌパコン屋はFortranしか本気でコンパイラを使ってない。


784 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 21:42:40 ]
>>783
×使ってない
○作ってない


785 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 21:45:54 ]
スパコンは並列化がキモだから、
並列化コンパイラの作りやすい Fortran を作りたがるのかもね。
言語仕様も単純で作りやすいし。

786 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 22:00:50 ]
質問です。
vectorのイテレータが有効なイテレータかどうか調べる方法を教えてください。

787 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 22:04:23 ]
質問です。
ポインタが有効なポインタかどうか調べる方法を教えてください。

と同じく、ありません。

788 名前:785 mailto:sage [2008/02/19(火) 22:30:42 ]
>>787
わかりました。
ありがとうございます。

789 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 22:34:26 ]
有効なポインタの全てと等しくならなければ有効・・・かも。
大小比較演算子使えるなら簡単になる。
当然、親となる配列が固定されていないと無理だが。
でも、こういうことしていいのかは微妙。
有効に見えるけど、指してる所が違うとかありうるし。

790 名前:786 mailto:sage [2008/02/19(火) 22:40:03 ]
vec.begin() < itr && itr < vec.end()

こんな感じでやっていたのですがこれでいいのか不安でした。



791 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 22:42:01 ]
やるなら vec.begin() <= itr かと。

それで一応どこか有効な要素は指してるかもしれないが、
「元々指していた箇所から決して動いていない」
ということまでは保証してくれない。

792 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 23:00:47 ]
非常に厳密に言えば>>790のコードは全く意味がない
そのコードを実行してよい事前条件が、まさに itr が有効なイテレータであることなので

793 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 23:43:39 ]
>>790
reallocateされた場合どうすんのよ?

794 名前:デフォルトの名無しさん mailto:sage [2008/02/19(火) 23:55:31 ]
なんだかんだいっても、あれだよあれ。

795 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 00:12:26 ]
メジャーリーグに興味持ち始めた頃、STL vs ATLってのがあって何かと思ったら
セントルイス・カージナルス対アトランタ・ブレーブスだった。

796 名前:デフォルトの名無しさん [2008/02/20(水) 09:16:18 ]
>vectorのイテレータが有効なイテレータかどうか調べる方法を教えてください。
>vec.begin() < itr && itr < vec.end()

自分もこれに関する情報欲しい。
良い記述があれば教えてキボン!

797 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 09:26:21 ]
しかしイテレータをそんな長く持ってるのって
プログラムを考え直した方がよいような

798 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 09:35:17 ]
いや、長く持つんじゃなくて、取得した直後に調べたいんだけど。

799 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 09:36:58 ]
*itr
で対象をproxyにしてis_valid()でも持たせたら?

800 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 09:44:22 ]
そのis_validの実装をどうするかの話をしてるんだろ…



801 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 10:16:45 ]
盛り上がってきますたw

802 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 10:25:13 ]
>>798
本当に「取得した直後」なら、i != vec.end()でいいのでは。

803 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 10:35:54 ]
サンクス>>802
絶対あってる?保障してくれる?

804 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 11:09:57 ]
>>803
どんな手段で取得した直後を想定しているの?

805 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 11:10:48 ]
どれだけ力強く保証したって、しょせん名無しのレスだぜ。

806 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 11:12:20 ]
こんなに調べる気ゼロな奴だと知ってたら、大嘘教えたのにな。

807 名前:803 mailto:sage [2008/02/20(水) 11:14:32 ]
>>804
 >>745- のような使い方です。

808 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 11:16:06 ]
>>806
本人からすると、ここで質問することだって調べる気でしょ。
そういう破壊的なことするのは良くないお( ^ω^)

809 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 11:20:42 ]
答になってないぞ。
>>745に書いてあるのは「取得したあとにやりたいこと」。
質問は「どんな手段で取得した直後を想定しているのか」だ。

810 名前:803 mailto:sage [2008/02/20(水) 11:30:31 ]
>>809

ですから、

vector::insertするためにはイテレーターが要りますよね?

で、item[6] としてイテレーターを取得したときに、そのイテレーターは有効なのか無効なのか、という判定。



811 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 11:51:08 ]
>>810
イテレータを取得する前に検査すべき。
例えば、std::vector<int> foo(5); std::vector<int>::iterator it = foo + 6;の結果は鼻から悪魔。

812 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 11:54:57 ]
>>810
item[6] ではイテレータを取得できないと思うよ
item.begin() + 6 のことか?
itemの6番目の要素が存在するなら、当然有効だし、
存在しないなら、何が返ってこようかくるまいが item.begin() + 6 を実行した時点でアウト

813 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 11:58:27 ]
>>810

よくわからんが、こういうことか?

void foo(vector<int>& v, int index) {
vector::iterator iter = v.begin() + index; // この iter は有効か判断したい.
v.insert(iter, 5);
}

ならば、こう書けば良い

void foo1(vector<int>& v, int index) {
if (v.size() < index) v.resize(index); // iterが必ず有効になるように、事前にvectorを拡大する.
vector::iterator iter = v.begin() + index;
v.insert(iter, 5);
}

void foo2(vector<int>& v, int index) {
if (v.size() < index) throw std::invalid_argument("index が大き杉"); // 範囲外なら例外を投げる.
vector::iterator iter = v.begin() + index;
v.insert(iter, 5);
}

814 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 12:15:16 ]
作った直後で無効なイテレータってあるのか?
作ること自体が違法だったり、作った後に無効になったりするのなら分かるんだが・

815 名前:810 mailto:sage [2008/02/20(水) 12:20:17 ]
>>813
やりたいことは、
ある行の後に1行追加したい、
だから、foo1でできるのはできます。

でも、ある行の後に1行追加するメソッドくらい、std::vectorとかが標準で持ってて欲しいと思うお。

816 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 12:33:35 ]
>>815
却下だな。
- 勝手に resize() するなら、途中の要素を何で埋めるか指定しないといけない。
- 挿入位置は iterator で指定するのが標準コンテナの流儀なのに、この場合だけ
インデックスで指定するのはおかしい。
- vector のメンバにしてもユーザーが実装しても効率などは変わらない。
標準で持っていたほうがいい理由が何も思いつかない。

817 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 12:35:35 ]
>>814
作った直後のイテレータは、コンテナの中身を指しているか、end()と等値か、だよな。
だからこっちは「本当に作った直後なら、!= vector.end()との比較でいい」って言ってるのに、
この質問者、「自分の訊きたいこと」と「自分の訊いていること」を一致させられないんだよ。

818 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 12:57:08 ]
おまえら頑張ってるが、実行効率も考えろ。
結果的に再取得したほうが良かったりして。

819 名前:786 mailto:sage [2008/02/20(水) 13:51:57 ]
いろいろ勘違いしていました。
実際はイテレータじゃなくてただのインデックスでした。
0<=index<vec.size()
で十分でした。

イテレータの場合は持ってる間vectorを変更しないようにしています。

820 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 13:53:28 ]
エエェェェ



821 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 14:18:16 ]
>>819
う゛ーう゛ー

822 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 14:20:36 ]
これは酷い釣りだ…

823 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 16:22:14 ]
結論としてイテレーターは役立たずでOk?

824 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 16:30:10 ]
list をイテレータなしでというのはちょっと
vector にはいらないけどさ

825 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 16:37:03 ]
listの返したイテレータが無効になるタイミングって、
list本体が破棄された場合と、イテレータ先がeraseされた
時だけでしょうか?

826 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 16:46:18 ]
元からC++にあった下位概念(ポインタ)が要求するメモリ構造を持っているvectorは、
後から加わった上位概念(イテレータ)を使わずとも、下位概念のやり方で各要素を見ていける、
だから「必須ではない」・・・という意味では、無くてもいいかもね。

実際には、stringやlistがbegin() end()してる中、vectorだけ&vec[0]とか使ってポインタでいじるのは
えらく不自然だから、vectorもイテレータで扱ってしまうけれども。

827 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 18:04:53 ]
>>825
合ってる(要素を消す関数はerase()以外にもあるけど)。あと標準には
list1.splice(list2);
するとlist2へのイテレータが全部無効になる、と書いてあるけど、
実際にはほぼ間違いなくlist1への有効なイテレータになる。
これは標準の方が訂正される可能性が高い。

828 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 19:40:59 ]
>>827
返答ありがとうございます。
listに要素追加したときイテレータを保存しておいて、
それを別なコンテナでインデックス化するってな使い方を
しても大丈夫そうですね。

spliceの
>実際にはほぼ間違いなく
ってところはちと怖いので、使用は避けときます。

829 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 21:01:56 ]
>>827
最新のドラフトだと 「移動した要素を指し続ける」 と書いてあるね。

830 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 21:36:58 ]
250. splicing invalidates iterators
Section: 23.2.3.4 [list.ops] Status: WP Submitter: Brian Parker Date: 2000-07-14

void splice(iterator position, list<T, Allocator>& x);
invalidates all iterators and references to list x.

This is unnecessary and defeats an important feature of splice. In fact, the SGI STL guarantees that iterators to x remain valid after splice.


WPってWorking Paperってなってるけど一度却下されてるんだよね。
で、最新のドラフトだとC++0xで修正されることは決定?

WP The proposed resolution has not been accepted as a Technical Corrigendum, but the full WG21 committee has voted to apply the Defect Report's Proposed Resolution to the working paper.




831 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 21:44:24 ]
N2461 だと次のように書いてある。

23.2.3.4 list operations

void splice(const_iterator position, list<T, Allocator>&& x);

4 Effects: Inserts the contents of x before position and x becomes empty.
Pointers and references to the moved elements of x now refer to those same elements
but as members of *this.
Iterators referring to the moved elements will continue to refer to their elements,   ← ここ
but they now behave as iterators into *this, not into x.

832 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 21:49:02 ]
moveの導入による影響おそるべし

833 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 21:53:24 ]
>>831
Working Draftか。
そうなりそうだね。

834 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:02:47 ]
>>832
list の splice は,標準ライブラリへの move の本格導入以前から,
auto_ptr と並ぶ標準ライブラリにおける move の代名詞だったような?
現行の規格が不必要に制限が強すぎた
(iterator の stability を保証しなかった) だけで,
move 導入とは直接関係ないんじゃないですかね?

>>831の splice の第2引数が右辺値参照型に変更されたのも
単に一時変数を渡すことができるようにしただけでしょうし.

835 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:05:17 ]
rvalue reference うぜえな。。 基本仕様としては
これが一番インパクトでかいかな。

836 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:07:39 ]
concept 周りが間に合えばあれも相当インパクト大きいのでは

837 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:07:54 ]
今まで
const Widget operator+(Widget, Widget)
とかしてたものが
Widget&& operator+(Widget, Widget)
になるのか。


838 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:08:37 ]
テンポラリオブジェクトを渡せるようになるのはいいのだが、
そのせいで左辺値参照でいい状況でもムーブが発生するのが微妙だな。

839 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:26:14 ]
以下は C++0x を前提にしたレスです.スレ違いですいません.

>>837
Widget の実装と operator+ の機能によりますけれど
値で返すのと参照で返すのでは基本的に意味が違ってしまうのでは?
で, move の恩恵を受けたければ Widget を move 可能にした上で
Widget operator+(Widget, Widget)
となるのが一般的かと思います.

>>838
>そのせいで左辺値参照でいい状況でもムーブが発生するのが微妙だな。
その微妙になる具体例ってどんなのがありますかね?

840 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:37:12 ]
l1.splice(it, l2);

右辺値参照の場合
1. l2 -> x のムーブ
2. x のノードを l1 に付け替える

左辺値参照の場合
1. l2 のノードを l1 に付け替える



841 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:42:46 ]
>>839
戻り値をWidgetにしてしまうと代入できてしまうので
constをつけてるんだけど、

@const Widget operator+(const Widget&, const Widget&);

AWidget&& operator+(const Widget&, const Widget&);

現在は@のようにしてるけど、C++0xからはAでいいかなと思った。
どちらも
Widget w1, w2, w3;
if( (w1 = w2) = w3 )
のようなケアレスミスをコンパイルエラーにしてくれると思ったけど、
Aだと (w1 = w2) = w3 はOKになってしまうか。右辺値参照に左辺値
は代入できるか。



842 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:44:44 ]
const Widget operator+(const Widget&, const Widget&);

と書いた場合、const Widget はムーブできるのか?

843 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:44:56 ]
>839
>838 じゃないけど。
値渡しにした段階でコピーが発生しちゃうから、

Widget&& operator+(Widget&&, Widget&&);
Widget&& operator+(Widget&&, const Widget&);
Widget&& operator+(const Widget&, Widget&&);
Widget operator+(const Widget&, const Widget&);

頑張るんならこうなるんじゃないの?
std::string の operator+() はこうなってるが。

あと、微妙ってのは左辺値参照なら単純にアドレス渡すだけで済んだものが、ムーブ処理が発生しちゃうのが嫌ってことなんじゃないかと。
で、↑はそのためにオーバーロードしてるけど。

844 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:46:52 ]
>>840
引数のl2は右辺値という前提だよね。そうするとmoveの分だけ効率が
悪くなるということかな。

845 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:51:32 ]
>>842
ん?メイヤーズの本で推奨されてたから従ってる。

>>843
ドラフト見たところでは、例えば
Widget&& operator+(Widget&& lhs, const Widget&& rhs);
の場合、両方の実引数にWidgetの一時オブジェクトを
渡すとlhsとrhsは右辺値になって、両方に左辺値を渡すとlhsとrhsは
左辺値になるという理解でいい?

846 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 22:55:53 ]
>>840
現行の list の splice の意味からすると,
splice という名前に前者の操作を overload させると混乱するのでは?
前者は最新の working draft に従えば,例えば
l1.splice(it,decltype(l2)(move_iterator(l2.begin()),move_iterator(l2.end())));
と書けると思いますけれど,これではダメなのですか?

あと,「左辺値参照の場合……」「右辺値参照の場合……」という書き方を
されていますけれど, l2 の型が右辺値参照型か左辺値参照型か,ということですか?
もしそうだとすると,l2 はそのままでは常に左辺値として扱われるので,
void splice(iterator, list<T,A>&);

void splice(iterator, list<T,A>&&);
があった場合には, l2 が右辺値参照型か左辺値参照型かに関わらず
常に前者が呼ばれると思います.


847 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:00:25 ]
しかし void splice iterator, list<T,A>&); は存在しない

848 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:03:20 ]
>>841
一時オブジェクトに対するメンバ関数呼び出しの overload は
右辺値参照型の *this への拡張が対応するかと思います.

www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2439.htm

例えば,右辺値に対して Widget::operator=(const Widget&) を禁止したければ

class Widget{
Widget& operator=(const Widget&) & { ... }
Widget& operator=(const Widget&) && = delete;
...
}

上記のようになるかと思います.従って Effective C++ にある>>845の記述は
C++0x では deprecated になるかと思います.

849 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:06:33 ]
>>842
move はそのソース (move 元) に対して破壊的操作を行うことになるので
戻り値に対して const を指定しているとその戻り値に対して
move を行うことはできなくなると思います.
Widget& Widget::operator=(const Wideget&); // copy assignment

Widget& Widget::operator=(Wideget&&&); // move assignment
があった場合,>>842の operator+ の戻り値に対しては
オーバーロードの優先順位を解決した結果, copy assignment が呼ばれるかと.

850 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:06:55 ]
dequeとvectorの速さ比べをしてみた(gcc 3.4.5 mingw)

for(i=0; i < num; i++){
 foo += v[i];
}

みたいなの。

vectorの先頭をポインタに渡してポインタ経由でアクセス
>>>>>>vectorを[]でアクセス>>>vector をiteratorでアクセス=dequeをiteratorでアクセス
>>>>>>>(越えられない壁)>>>>>>dequeを[]でアクセス

dequeがあればvectorはいらない子みたいなカキコがあったけど、やっぱvectorはやればデキる子だよ。



851 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:15:29 ]
>>843
ありがとうございます.微妙な具体例が理解できました.
これを気にするならば overload 頑張るしかないですね.

852 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:18:07 ]
オーバーロードで解決は出来るけど、
沢山あると大変だね。

853 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:27:12 ]
蛇足ですけれど,>>843は書かれているような「微妙な状況」の他に,
引数が一時オブジェクトで,その一時オブジェクトのバッファが
結合後の文字列を保持できる余裕がある場合に,
バッファの再確保を回避できる最適化を積極的に活用できる
というのもあるかと思います.

854 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:34:05 ]
>>847
元々 splice は move (破壊的コピー) を行うという意味づけであり
右辺値と左辺値を区別する必要はなく,
void splice(iterator, list<T,A>&);

void splice(iterator, list<T,A>&&);
をオーバーロードする必要もないと自分は思います
(し,おっしゃるとおり working draft も今のところそうなっています)

855 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:35:07 ]
>>850
vectorアクセスするのにiterator経由より[]の方が速いって謎すぎる。
何らかの理由で最適化に失敗してるか、assertが効いてるんじゃ?

856 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:48:29 ]
>>855
最適化オプション何もなしだお

857 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:49:40 ]
>>855
ちなみに、倍速くらい
ポインタにすると[]のさらに倍
ちなみにdequeの[]はvectorの[]の4倍遅い

858 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:50:03 ]
-O2つけて測定コード毎最適化で消してしまえ。

859 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:50:18 ]
あほすぎ。

860 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:54:00 ]
ふつーSTLは最適化かけて実測するもんだと思ってたのだが、違うのか?




861 名前:デフォルトの名無しさん mailto:sage [2008/02/20(水) 23:57:15 ]
STL に限らず、実測は最適化かけてからやるのが普通。
最適化しない場合の影響を調べるのでもない限りは。

862 名前:デフォルトの名無しさん mailto:sage [2008/02/21(木) 00:05:39 ]
ふつー、最適化をかけるとvetor::operator[]はポインタアクセスと同じコードに
展開される。実際、gcc3.4.6 -O2ではそう。






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

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

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