おしえてください。
以下のコードの中で、
m_lst(CList型)のリストデータを、
ある条件に合致する複数データを削除したいとおもている
のですがうまくいきません。
m_lst.RemoveAt(pos);
のコードに一度入ってしまうと、
ポジションの値がおかしくなってしまうようなのですが...
なにか対策または違う方法はないでしょうか?
while(pos)
{
Tool = m_lst.GetNext(pos);
if(Tool != Line)
{
m_lst.RemoveAt(pos);
}
}
> if(Tool != Line)
> {
> m_lst.RemoveAt(pos);
> }
これって、該当の値のPOSITIONでないですよね?
(posは次の値を指している)
消すのは今見ているのだから、GetPrevでPOTIONを変更して削除しないといけないです。
サンプル)
CList< int, int > mylist;
for ( int i = 0; i <= 10; ++i )
{
mylist.AddTail( i );
}
POSITION pos = mylist.GetHeadPosition();
while ( pos )
{
int n = mylist.GetNext( pos );
if ( n == 5 )
{
// posは6を位置を指している
POSITION temp = pos;
mylist.GetPrev( temp );
mylist.RemoveAt( temp );
}
std::cout << n << std::endl;
}
「CListなんか使わない」がもっとも簡単に思えます。
#include <iostream>
#include <list>
// 偶数に対しtrueを返す。
struct is_even {
bool operator()(int x) const {
return x % 2 == 0;
}
};
int main() {
std::list<int> li;
// 0, 1, 2 ... をリストに繋ぐ
for ( int i = 0; i < 10; ++i ) {
li.push_back(i);
}
// 偶数を取り除く
li.remove_if(is_even());
// リスト内をプリント
for ( std::list<int>::iterator iter = li.begin();
iter != li.end(); ++iter ) {
std::cout << *iter << ' ';
}
std::cout << std::endl;
return 0;
}
/* 実行結果
1 3 5 7 9
*/
GetTailPositionで最後を取得してGetPrevで遡りながら消す。
GetPrevしてから消せば、大丈夫ではないかな。
これだとずれないと思う。
回答ありがとうございました。
>これって、該当の値のPOSITIONでないですよね?
>(posは次の値を指している)
そうでした。
POSITIONがおかしくなってしまったのも
次の値を削除してしまっていたため、
さらにその次の値を見ようとPOSITIONを取得しようとしても
既に削除されている(次の値のPOSITIONは値に付随して保存されている?)
ためだったのだとおもわれます。
>「CListなんか使わない」がもっとも簡単に思えます。
今、PGの不具合修正を行っているため、
安易に変数の型を変更できない状況でした。
今後の参考にさせていただきます。
補足。
削除先のPOSITIONとGetPrevで取得するPOSITIONは別の変数にしておいて
削除が終わったら削除先に取得したものを突っ込めばよろしいかと。
そこまでしなくても大丈夫かもしれないけど。
> (次の値のPOSITIONは値に付随して保存されている?)
MFCのソースをみてみるとわかると思いますが、
POSITIONはリンクテーブル型のポインタをPOSITIONでキャストしているものです。
afxtemp.h内
>template<class TYPE, class ARG_TYPE>
>class CList : public CObject
>{
>protected:
> struct CNode
> {
> CNode* pNext;
> CNode* pPrev;
> TYPE data;
> };
ツイート | ![]() |