[表示 : 全て 最新50 1-99 101- 2chのread.cgiへ]
Update time : 04/24 09:47 / Filesize : 46 KB / Number-of Response : 180
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


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

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



1 名前:デフォルトの名無しさん [2009/01/11(日) 11:13:44 ]
C++標準ライブラリの一つ、STLについて。

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

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

60 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 02:01:24 ]
ポインタの加算演算って型の大きさに合わせて保存してるアドレスの値増減するだけじゃないの?
デリファレンスしてなくてもだめなことあるの?

61 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 02:03:46 ]
>>60
ヌルポインタになるかもしれない

62 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 04:03:58 ]
>>57
p1==p3が保証されないのってマジ?
もしそうならポインタ演算とか怖くて出来なくなるな

63 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 06:06:06 ]
>>60
配列(非配列は要素数1の配列とみなして)の要素か終端までを指すように演算することは
できるけど、その範囲外を指すようにした場合は未定義動作になる。

char a[10];
a - 1; // 未定義動作
a + 10; // 終端なのでまだ大丈夫
a + 11; // 未定義動作

64 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 06:10:58 ]
v.erase( v.end() );
v.erase( v.end(), v.end() );
同じようで違うとゆー

65 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 07:35:54 ]
>>63
ほんとだ。

5.7 Additive operators p5 より
> When an expression that has integral type is added to or subtracted from a pointer,
> the result has the type of the pointer operand. ...
> ... If both the pointer operand and the result point to elements of the same array object, or
> one past the last element of the array object, the evaluation shall not produce an overflow;
> otherwise, the behavior is undefined.

66 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 10:32:33 ]
>>57->>68
この中にウソを言っているものがいる。
このうそつきめ!

67 名前:67 mailto:sage [2009/01/24(土) 10:37:11 ]
   *      *
  *     +  うそです
     n ∧_∧ n
 + (ヨ(* ´∀`)E)
      Y     Y    *


68 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 11:05:25 ]
なんで皆騙されてんだよw
(a+11)-1 != a+10 が成立する訳ないだろ、そんなんじゃとてもコンパイラ作れねーよ。
もちろん *(a+10)とか*(a-1)とかを使ったら無効なアドレスの参照だから何が起こるかわかんないけど、
ポインタ演算の時点では問題ないっての。





69 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 11:25:08 ]
a+11がオーバーフロー起こす可能性があって、
その場合-1しても戻るとは限らないってことだろ
>>65によると

70 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 11:53:33 ]
ちょっと込み入った算式に入れてたりしたら、マズイ場合あるな。
もっとも、ポインタ値みたいなものへの計算値に基づいて
更に計算、みたいな恐いことはまずやらんけど。

71 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 12:07:29 ]
>>68
実装依存なことと規格で保証されていることの区別のつかないバカ

72 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 12:29:02 ]
>>71
バカと言えば勝った気になってるバカ

73 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 12:32:53 ]
実際の配置からすれば、ちょっと飛び出しても大丈夫ではあるよね

74 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 12:40:36 ]
>>68
オーバーフロー時に例外が発生するCPUでは
(a+11) を実行した時点で例外が発生して比較自体が行われない可能性がある。

75 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 15:26:42 ]
大人しくa+(11-1)しろってことだよ。

76 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 16:38:12 ]
もちろん、自分がコンパイラを作るときは、
(a + 11) - 1をa + 10と同じ結果にしても構わないんだよ。

77 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 23:50:11 ]
int *p=0; // nullpointrt;
p+=1;
assert(p!=0);

ヌルポインタをインクリメントした結果が、非ヌルになることも保証されないんだよね
やっぱり

78 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 23:55:00 ]
オプション次第で変なアドレスを指す際にエラーとするコンパイラがあってもいいんじゃね。



79 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 23:57:03 ]
その辺をどう扱ってもいいというのがすなわち未定義ということだ

80 名前:デフォルトの名無しさん mailto:sage [2009/01/24(土) 23:59:19 ]
文句があるならCの親のBCPLに言いな。

81 名前:デフォルトの名無しさん mailto:sage [2009/01/25(日) 00:12:29 ]
DSPなんかで、そういう問題が起こるケースがあったと思う

int *getptr(int x) {
static array[0x2000];
return array+(x*10);
}

offsetの計算を16ビットレジスタでやった方が高速化される環境だと
最適化によって x*10の結果の上位を捨てて下位16ビットしか使わないコードが生成されても文句が言えない

82 名前:デフォルトの名無しさん mailto:sage [2009/01/29(木) 13:47:49 ]
VS2005で動いている既存のプロジェクトにSTLport5.1.0を導入しようとしているのですが
typeinfo.hのbad_castとbad_typeidがC2039・C2873エラーになります。
解決の方法がありましたら教えてください

個人の趣味で作ってるプログラムだし、例外捨ててコメントアウトかな…

83 名前:デフォルトの名無しさん mailto:sage [2009/01/29(木) 14:02:31 ]
>>82
んー?
ml.tietew.jp/cppll/cppll/thread_articles/5592

84 名前:82 mailto:sage [2009/01/29(木) 15:10:00 ]
ありがとう、見てみました
boost使ってないので少しわからないとこもありますが

5.0〜ならいける的な事が書いてあったりしますが、その後のバージョンなんですよね…

自分はtypeinfo.h内の::bad_cast記述部分二対して 存在しないのでエラーになっているのですが
上記ページだとtypeinfo.hをインクルードしているとかで混乱します

85 名前:デフォルトの名無しさん mailto:sage [2009/01/29(木) 20:13:48 ]
同じバージョンじゃないから確認とかしてないから話半分に

IOSTREAM(S)をどっちで使うか設定するとこあるから
それに似たbad_cast(exception)とかあるかも

86 名前:デフォルトの名無しさん [2009/01/30(金) 20:36:39 ]
123.writeboard.com/27c7a247acc07351e/login
pass:pgtwit

87 名前:デフォルトの名無しさん mailto:sage [2009/01/30(金) 21:17:24 ]
ついったー(笑)でやれ

88 名前:デフォルトの名無しさん [2009/02/01(日) 11:42:50 ]
VC2005 Express Edition使っているんだけど
streambuf_iteratorってどのヘッダインクルードすればいいの?



89 名前:88 mailto:sage [2009/02/01(日) 12:09:33 ]
ごめん
istreambuf_iteratorにしてなかったから駄目だったんだ

90 名前:デフォルトの名無しさん [2009/02/02(月) 14:05:11 ]
>>88

#include <iterator>

91 名前:デフォルトの名無しさん mailto:sage [2009/02/04(水) 16:24:38 ]
VC9+MFCのアンマネージでmapは使えないのでしょうか?
xtreeでアクセス違反が出るんですが・・・

92 名前:デフォルトの名無しさん mailto:sage [2009/02/04(水) 16:54:44 ]
>>91
それは何か使い方が間違っている。そしてそれは恐らくは、STLに直接関係ない。

93 名前:デフォルトの名無しさん [2009/02/04(水) 18:31:55 ]
すみません、vectorで質問なのですが
//------------------------------------
#include <vector>
using namespace std;

int _tmain(int argc, char* argv[])
{
vector<bool> bool_vect(10);
bool& b = bool_vect[5];

vector<int> int_vect(10);
int& i = int_vect[5];

return 0;
}
//-------------------------------------

bool のほうで以下のコンパイルエラーが出てしまいます
error C2440: '初期化中' : 'std::_Vb_reference<_MycontTy>' から 'bool &' に変換できません。
with
[
_MycontTy=std::vector<bool,std::allocator<bool>>
]

回避する方法はないでしょうか?

94 名前:デフォルトの名無しさん mailto:sage [2009/02/04(水) 18:36:51 ]
何が目的で参照をとろうとするの?必要性が感じられないのだけど。

95 名前:デフォルトの名無しさん mailto:sage [2009/02/04(水) 18:40:22 ]
>>93
vector<bool>は使うなカス
詳しくはEffectiveSTL

96 名前:デフォルトの名無しさん mailto:sage [2009/02/04(水) 18:44:02 ]
>>93
内部がビット操作だったはず

97 名前:デフォルトの名無しさん mailto:sage [2009/02/04(水) 19:57:39 ]
なるほど、「std::vector<bool>はコンテナの要件を満たしていない。 」のですね。
ありがとうございます。

>>94
実際に必要性が出ているのは、もう少しややこしいコードで、
任意の型の参照を引数に取る関数に
その任意の型のvectorの要素をそのまま渡したかったのです。
とりあえずはboolだけ特殊化して回避することにします。
ただ、任意の型に対応するならvectorじゃなくて配列にした方がいいのかもしれないですね。

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

98 名前:デフォルトの名無しさん mailto:sage [2009/02/04(水) 20:21:16 ]
>>97
vector<T>::reference使えばいけるはず。



99 名前:デフォルトの名無しさん mailto:sage [2009/02/04(水) 21:23:37 ]
>>98
おぉ、STLっぽくなりました。
ありがとうございます。

100 名前:デフォルトの名無しさん mailto:sage [2009/02/04(水) 21:42:37 ]
bool なら deque 使うだろjk

101 名前:デフォルトの名無しさん mailto:sage [2009/02/05(木) 02:15:21 ]
deque<bool>とlist<bool>はコンテナだっけ

102 名前:デフォルトの名無しさん mailto:sage [2009/02/05(木) 02:41:59 ]
コンテナだよ

103 名前:デフォルトの名無しさん mailto:sage [2009/02/07(土) 10:45:12 ]
list<bool>・・・
使い道が思いつかないな

104 名前:デフォルトの名無しさん mailto:sage [2009/02/07(土) 11:07:37 ]
つbitset


105 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 15:26:30 ]
vector<int>のインスタンスがa,b,cとあって、aとbの要素をつなぎ合わせたcを作るにはどう書くのが一番シンプルですか?
例えばaに1,2,3が、bに4,5,6が入っている時、cを1,2,3,4,5,6にしたいです。

106 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 15:33:22 ]
c=a; c.insert(c.end(),b.begin(),b.end());

107 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 15:36:52 ]
>>106
ありがとうございます。

108 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 15:38:18 ]
intのvectorならこっちの方が速いし自然だよ
>>106は中身がクラスの場合用

size_t a_n = a.size();
size_t b_n = b.size();
std::vector<int> c(a_n+b_n);
memcpy(c.begin(),a.begin(),a_n);
memcpy(c.begin()+a_n,b.begin(),b_n);



109 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 15:48:05 ]
>>108
なるほど、どうもです。

110 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 16:03:25 ]
std::vector<int> v = (v1|pstade::oven::jointed(v2))|pstade::oven::copied;

111 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 16:04:12 ]
>>108
memcpy使うのは最悪だろ

112 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 16:09:40 ]
>>111
vector と PODの組み合わせなんだから別にいいだろ

113 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 16:20:27 ]
ovenは相変わらず反則だな

114 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 16:26:51 ]
わざわざ型安全性を捨ててメモリ不正アクセスの危険を冒してまでmemcpyを使う必要はなかろう
コピーするにしても std::copy を使うべき

よっぽど速度が遅くて困らない限りは >>106 で十分

115 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 16:33:50 ]
>>108
さっそくバグってるなw
intが1byteの環境はあんまりないよね。

116 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 16:36:48 ]
自分の場合こんな関数作ってユーティリティに突っ込んである
template<typename T, typename Range>
inline void range_extend(T &t, const Range &r)
{
t.insert(t.end(), boost::begin(r), boost::end(r));
}
// c = a; range_extend(c, b);

117 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 16:37:59 ]
>>108
vectorのイテレータがポインタではないライブラリではコンパイルエラーだぞ
c.begin() は &c[0] に置き換えないとダメ

118 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 16:38:09 ]
というか >>108 は memcpy にイテレータを直接渡してるじゃねーか
こんなん論外だ



119 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 16:43:56 ]
!#include <iostream>
#include <vector>

#include <pstade/oven/jointed.hpp>
#include <pstade/oven/sugar.hpp>
#include <pstade/oven/copied.hpp>
#include <pstade/oven/io.hpp>
#include <pstade/oven/identities.hpp>
#include <pstade/oven/initial_values.hpp>

int main(int, char *[])
{
namespace ov = pstade::oven;
using namespace pstade::oven::sugar;
std::vector<int> a = ov::initial_values(1, 2, 3), b = ov::initial_values(4, 5, 6);

std::vector<int> v = (a >> b)|ov::copied;

std::cout << (v|ov::identities);
}

sugarで(問題部分だけは)さらに短くかけるらしいです

120 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 16:59:27 ]
>よからぬ場所に出入りしていると、当てにならない人物に出くわし、 &v[ 0 ] の代わりに
>v.begin() を使うことができると言われるかもしれない。
(中略)
>率直に言えば、 &v[ 0 ] の代わりに v.begin() を使うよう勧めるような人たちと付き合っているなら、
>交友関係を考え直す必要がある。

スコット・メイヤーズ著 ピアソンエデュケーション刊
Effective STL〜STLを効果的に使いこなす50の鉄則 p.73

121 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 19:03:40 ]
そもそも >105 の質問は「一番シンプル」な方法を求めているんだから >106 が正解。

再確保によるロスを防ぎたかったら c.reserve(a.size() + b.size()) で準備してから
実行すればいい。 >108 の resize() では無駄な初期化( int の場合は 0 フィル)が入る。

要素型に依存する必要はまったく無い。

122 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 19:08:49 ]
int の場合に memcpy() に最適化するというのも、ライブラリの実装やコンパイラが判別できる
範囲の話。

123 名前:デフォルトの名無しさん mailto:sage [2009/02/11(水) 19:55:23 ]
>>119

pc11.2ch.net/test/read.cgi/tech/1231080841/36

identitiesになにするもの?

p-stade.sourceforge.net/oven/doc/html/oven/range_adaptors.html#oven.range_adaptors.identities

www.codeproject.com/KB/stl/oven.aspx
の9.22を見る限りでは、そのままのRangeが返ってくるみたいだけど・・・



124 名前:統合しました。。。: mailto:sage [2009/02/14(土) 18:06:57 ]

pc11.2ch.net/test/read.cgi/tech/1234420483/

真・スレッドリスターター。。。( ̄ー ̄)ニヤリッ

125 名前:デフォルトの名無しさん mailto:sage [2009/02/16(月) 17:21:23 ]
質問です。
STLはヘッダにその実装が書いてあるわけですが、
ということは「翻訳単位毎にコードが生成される」のでしょうか?

a,cpp
b.cpp
両方<vector>をincludeし、両方で vector<int> が使われていた場合、vector<int>のコードは2つ作られてしまうのでしょうか?
EXEファイルの容量がガンガン増えるような気がするのですが・・・

126 名前:統合しました。。。 mailto:sage [2009/02/16(月) 18:18:04 ]
>>125

pc11.2ch.net/test/read.cgi/tech/1234420483/

真・スレッドリスターター。。。( ̄ー ̄)ニヤリッ

127 名前:デフォルトの名無しさん mailto:sage [2009/02/16(月) 21:54:46 ]
>125
実装によるが、最終コードでは一つになっているのが普通。
C++ Templates The Complete Guide には 3 つのモデルが載ってる。概要は以下の通り。
1. Greedy Instantiation
翻訳単位ごとにインスタンス化するが、リンカで一つだけ残す。
2. Queried Instantiation
共有のデータベースを持ってそこに登録する。
3. Iterated Instantiation
リンク時に足りないものを検出してインスタンス化。

128 名前:停止しました。。。 mailto:sage [2009/02/17(火) 23:33:50 ]
真・スレッドリスターター。。。( ̄ー ̄)ニヤリッ



129 名前:デフォルトの名無しさん mailto:sage [2009/02/18(水) 09:28:58 ]
アヌスストッパーじゃないのか。

130 名前:デフォルトの名無しさん [2009/02/23(月) 18:07:27 ]
関数オブジェクトの使い方として、以下のような記述は許されますか?

// generate アルゴリズムを使ってコンテナに公差1の等差数列を代入する
template < class T > class Gens {
public:
  Gens() : s_( 0 ) {}
  Gens( T i ) : s_( i ) {}
  T operator () (){ return s_++; }
private:
  T s_;
};

int main() {
  vector< int > vector1( 20 );
  Gens< int > gens( 10 );                // 問題はココと
  generate( vector1.begin(), vector1.end(), gens ); // ココ
}

普通は
generate( vector1.begin(), vector1.end(), Gens< int >() );
のように書きますが、
あらかじめオブジェクトを構築しておいて、
そのオブジェクトを引数として渡すというものです。
上記の例ではあらかじめオブジェクトを構築することで
ジェネレータが作り出す数列の初項を10に設定しています。

131 名前:デフォルトの名無しさん mailto:sage [2009/02/23(月) 20:10:05 ]
>>130
全く問題ないよ

132 名前:デフォルトの名無しさん mailto:sage [2009/02/23(月) 21:15:07 ]
>>130
>上記の例ではあらかじめオブジェクトを構築することで
>ジェネレータが作り出す数列の初項を10に設定しています。
なら
generate( vector1.begin(), vector1.end(), Gens< int >( 10 ) );
でもインジャネーノ?


133 名前:デフォルトの名無しさん mailto:sage [2009/02/23(月) 21:28:02 ]
>>130
そもそも内部状態を持つ関数オブジェクトをアルゴリズムで使うのはよろしくない
www.kijineko.co.jp/tech/superstitions/functor-is-not-copied-in-algorithm.html

134 名前:デフォルトの名無しさん mailto:sage [2009/02/23(月) 21:49:05 ]
コピー禁止すりゃいいんじゃね?

135 名前:デフォルトの名無しさん mailto:sage [2009/02/23(月) 22:29:12 ]
誰にも突っ込んでもらえなかったけど、コピー禁止してどうやって渡すんだ orz

136 名前:デフォルトの名無しさん mailto:sage [2009/02/23(月) 22:33:29 ]
>>133
たしかに規格上は保証がないかもしれないが、なんだか屁理屈に聞こえる。

137 名前:デフォルトの名無しさん mailto:sage [2009/02/23(月) 23:43:39 ]
>>136
同感だな
内部状態を持つ関数オブジェクトって普通にありえるからな
なんか現実を無視して重箱のすみを突いているって感じだな

138 名前:デフォルトの名無しさん mailto:sage [2009/02/23(月) 23:53:59 ]
いや、これははまるぞ
移植してバグったとき、大変そうだ



139 名前:デフォルトの名無しさん [2009/02/24(火) 00:01:50 ]
ん?
マッサーの STL 本では generate のサンプルで内部状態を保持しているし
メイヤーズの Effective STL でも、関数オブジェクトの利点は
「必要に応じていくつでも状態を格納できること」と書いてるぞ?(たとえば p.161 )

述語は純粋関数でないとだめだけど。
サッターの C++ Coding Standardsでは
「述語は関数オブジェクトの部分集合である」( p.172 )としていて
すなわち述語でない関数オブジェクトは純粋関数でなくても良いということになってるぞ?

どっちなんだ。

140 名前:デフォルトの名無しさん [2009/02/24(火) 00:05:52 ]
ちなみに、generate の第三パラメータは述語ではないので、
(マッサー、メイヤーズ、サッターの本にあるとおり)
純粋関数でなくても良いということになる。

141 名前:デフォルトの名無しさん [2009/02/24(火) 00:12:15 ]
今、シルトの本も調べてみたが、やっぱり関数オブジェクトの利点として
「値を格納したり、追加機能を実装できる」( p.230 )と書いてるな。

142 名前:デフォルトの名無しさん mailto:sage [2009/02/24(火) 00:12:48 ]
すまん、全部 age ちまった・・・ orz

143 名前:デフォルトの名無しさん mailto:sage [2009/02/24(火) 00:44:58 ]
vectorの連続性と一緒だな
普通はコピーなんてしないし、規格作った方もそんなつもりじゃなかったけど
ちゃんと書いてないせいで信用できないし、コピーしちゃう実装を誰かが作っても責められない
そんな誰も得しない状態

0xで直るんかね

144 名前:デフォルトの名無しさん mailto:sage [2009/02/24(火) 00:52:16 ]
vectorの格納領域は「必ず」連続するようになったのは1998年以降だから
まぁ、いまどきのコンパイラならもう必ず連続すると考えていいんじゃないの。


145 名前:デフォルトの名無しさん mailto:sage [2009/02/24(火) 11:38:30 ]
std::vector<int> v;
v.reserve(10);
... // v に値を格納
std::copy(v.begin(),v.end(),std::ostream_itreator<int>(std::cout,","));

このコードの copy 内の ostream_iterator... の部分て何を行っているのですか?
コンテナの要素をループで書き出してるのは分かるのですが、内部でどのような処理をしているのでしょう?


146 名前:デフォルトの名無しさん mailto:sage [2009/02/24(火) 12:43:55 ]
>>138
俺もはまった
boost::refして誤魔化した

147 名前:デフォルトの名無しさん mailto:sage [2009/02/24(火) 12:53:46 ]
ええ、どこのベンダだよ

148 名前:デフォルトの名無しさん mailto:sage [2009/02/24(火) 16:00:32 ]
vectorの格納領域と同じで、標準化委員会がどっかで修正コメントだしてないのかな?



149 名前:デフォルトの名無しさん mailto:sage [2009/02/24(火) 16:14:34 ]
>>130
俺なら output_iterator を受け取る関数を作って back_inserter を渡す。
std::vector なら reserve してからね。

>>133
良くないのはそうだけど、総和とかには使うし、命名とかコーディングスタイルの話になるんじゃないか?

150 名前:デフォルトの名無しさん mailto:sage [2009/02/24(火) 18:48:24 ]
>>146
それどこのSTLライブラリ?
で、どんなコードではまった?

151 名前:デフォルトの名無しさん mailto:sage [2009/02/24(火) 20:48:17 ]
>>149
ライブラリの内部実装の話を命名やコーディングスタイルでどうするの?

152 名前:デフォルトの名無しさん mailto:sage [2009/02/24(火) 23:49:33 ]
>>145
ttp://msdn.microsoft.com/ja-jp/library/0c6y7x31(VS.80).aspx


153 名前:デフォルトの名無しさん mailto:sage [2009/02/25(水) 00:08:40 ]
>149
総和系なら accumulate があるべ。

154 名前:デフォルトの名無しさん mailto:sage [2009/02/25(水) 08:55:19 ]
状態を持つと並行処理できないじゃないか。

なーんてね

155 名前:デフォルトの名無しさん mailto:sage [2009/02/25(水) 09:03:23 ]
>>151
内部状態を持つ関数オブジェクトを使う話で、内部実装の話はしてないよ。
使わないほうがいいけど、使うなら注意を喚起するとか、専用の関数を作って封じ込めるとか、という話。

>>153
全くその通りでした。

156 名前:デフォルトの名無しさん mailto:sage [2009/02/25(水) 19:52:40 ]
mapは構造体をキーに持つことができないのでしょうか?
具体的には、mapを使って2枚の画像の対応点を記録しようとしています。

typedef struct point
{
int x;
int y;
}point;

map<point, point> correspond;
point p1, p2;
/*p1とp2の座標を入力*/

correspond.insert( pair<point, point>(p1, p2) );

としてコンパイルするとerror C2784が出ます。
環境はVS2008、XP SP3を使っています。

どうしたら解決できるでしょうか?

157 名前:デフォルトの名無しさん mailto:sage [2009/02/25(水) 20:04:06 ]
エラーの内容から二つのpointを比較できないコードであるということがわかるので、mapの為に比較関数を用意する。
方針としては、グローバルにpointの大小を判別するbool operator<(const point&, const point&)を定義するか、
correspondの宣言の歳にmap<point, point, compare_t> correspond(compare);とする
(ただしcompare_tは戻り値boolで引数に(const point&, const point&)を取ることができる関数オブジェクトまたは関数の型で
compareはそのインスタンス)

158 名前:デフォルトの名無しさん mailto:sage [2009/02/25(水) 20:25:45 ]
>>157
素早い回答ありがとうございます。
pointのxとyどちらでソートすべきか比較関数を用意してやればよいということでしょうか?



159 名前:デフォルトの名無しさん mailto:sage [2009/02/25(水) 20:32:21 ]
うん、例としては
bool f(const point& lhs, const point& rhs){
return lhs.x < rhs.x && lhs.y < rhs.y;
}
のようなものを定義して
map<point, point, bool(*)(const point&, const point&)> correspond(f);
かな?

operator<を使う方法についてはeffective C++とか参考にすれば、
綺麗に実装する方法が載ってると思う

160 名前:デフォルトの名無しさん mailto:sage [2009/02/25(水) 20:39:54 ]
>>159
具体例までありがとうございます。
map 比較関数 でググったらいくつか例も出てきたので出来そうです。

よく考えるとmapは2分木を利用してるんだから自前の比較関数を用意してやる必要があるのは当たり前ですね。
勉強になりました。

161 名前:デフォルトの名無しさん mailto:sage [2009/02/27(金) 20:33:14 ]
C++やSTLではコンテナの全要素を出力するときどのようにするのでしょうか?
kansai2channeler.hp.infoseek.co.jp/cgi-bin/joyful/img/8944.txt
今は上のようにやってます。
list vector mapやDataのようなクラスが増えていくにつれコードが増え、似たような処理が何回も出てきそうです

162 名前:デフォルトの名無しさん mailto:sage [2009/02/27(金) 20:37:20 ]
std::list<T>をTにすればコンテナ全種に使えるようになるはず。

163 名前:デフォルトの名無しさん mailto:sage [2009/02/27(金) 20:41:47 ]
よくわからないけどこういうこと?
template<typename T>
std::ostream &print(std::ostream &ost, const T &cont)
{
ost << "[";
std::copy(cont.begin(), cont.end(), std::ostreambuf_iterator<T::value_type>(ost, ","));
ost << "]";
return ost;
}

164 名前:デフォルトの名無しさん mailto:sage [2009/02/27(金) 20:50:54 ]
コンテナを取るんじゃなくて、algorithmみたいに範囲を取るようにすれ。

template<typename Iterator>
std::string to_str2(Iterator first, Iterator last) {
 std::ostringstream oss;
 Iterator it = first;
 oss << "[";
 if (it != last) {
  while (true) {
   oss << (*it);
   ++it;
   if (it == last)
    break;
   oss << ", ";
  }
 }
 oss << "]";
 return oss.str();
}


165 名前:デフォルトの名無しさん mailto:sage [2009/02/27(金) 20:51:31 ]
まぁそれだけだとlist<list<...>>みたいなのに適応できないけどな

166 名前:161 mailto:sage [2009/02/27(金) 23:02:22 ]
>>162
ほんとですね、全部なおしました
std::ostream& operator<<(std::ostream & rhs, const <T>& lhs)はダメなんですね
当たり前なんでしょうけど

>>163
こういう書き方もできるのですね、、、
p to_str(dlist)かp 'to_str(std::list<Data, std::allocator<Data> > const&)' (dlist)でgdbから呼べるのですが、
ostreamかtemplate使うと消える?みたいなのでObject.to_string()とテンプレートではないto_str(x)は用意するので
ostreamやostringstreamを極力使わずにできればなと

>>164,165
Iteratorの中身がコンテナじゃなさそうな場所に使ってみます

167 名前:デフォルトの名無しさん mailto:sage [2009/02/28(土) 00:04:03 ]
とりあえず、rhsは right hand side(右側)の略なんだから
lhs << rhs って形にしようぜw

168 名前:デフォルトの名無しさん mailto:sage [2009/03/02(月) 12:55:03 ]
関数オブジェクトにしといてfor_each()じゃだめなのか



169 名前:デフォルトの名無しさん mailto:sage [2009/03/03(火) 21:45:22 ]
>>168
それ、コードではどうやるの

170 名前:デフォルトの名無しさん mailto:sage [2009/03/04(水) 01:25:00 ]
こんな感じ?

template <class T>
struct Out {
void operator()(T& i) const {
std::cout << i << ' ';
}
};

int main()
{
int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::list<int> aa(a, a + sizeof(a) / sizeof(a[0]));

std::for_each(aa.begin(), aa.end(), Out<int>());
}

171 名前:デフォルトの名無しさん mailto:sage [2009/03/04(水) 12:40:27 ]
ostream_iteratorにassignという手も

172 名前:デフォルトの名無しさん mailto:sage [2009/03/04(水) 16:04:02 ]
例としてよく引き合いに出されるのは ostream_iterator に copy だと思うが・・・

173 名前:デフォルトの名無しさん mailto:sage [2009/03/04(水) 16:19:22 ]
for_eachを使うと copy よりも凝った出力形式を作れるってくらいかな

174 名前:デフォルトの名無しさん mailto:sage [2009/03/05(木) 09:49:02 ]
#include <pstade/oven/io.hpp>
#include <pstade/oven/make_range.hpp>

int main()
{
namespace oven = pstade::oven;
std::list<int> l = a|oven::copied;
std::cout << (oven::make_range(l)) << "\n";
}

175 名前:デフォルトの名無しさん mailto:sage [2009/03/10(火) 23:08:36 ]
>>136,143
www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#92
今のドラフトでは以下の記述が追加されている。
> algorithms that take function objects as arguments are permitted to copy those function objects freely

アルゴリズム内でどうコピーされるかは基本的に実装任せってことになるらしい。

for_each() の戻り値はまったく使えないことになりそうだ。

176 名前:デフォルトの名無しさん mailto:sage [2009/03/14(土) 16:56:46 ]
>>175
for_eachの戻りはコピーされた関数オブジェクトに内部状態が反映されてるんじゃなかった?

177 名前:デフォルトの名無しさん mailto:sage [2009/03/14(土) 18:17:17 ]
>176
関数オブジェクトに全要素を通して処理した結果の状態が保持されていることを期待するだろうが、
極端に言えば各要素の呼び出し毎に新しくコピーした関数オブジェクトを渡されたりすると、期待する
結果と異なる。
参照使うなりコピーされても大丈夫なようにはできるからまったく使えないは言い過ぎ。
とはいえ、そういう用途なら accumulate 使えばいいじゃん、とは思う。

178 名前:デフォルトの名無しさん mailto:sage [2009/03/14(土) 18:22:46 ]
boost::ref使って渡せばいいんじゃないか。boost::mpl::for_eachではうまくいった



179 名前:デフォルトの名無しさん mailto:sage [2009/03/18(水) 22:23:42 ]
 






[ 新着レスの取得/表示 (agate) ] / [ 携帯版 ]

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

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