CListのデータを削除

解決


阪神  2005-09-15 20:35:56  No: 59028

おしえてください。

以下のコードの中で、
m_lst(CList型)のリストデータを、
ある条件に合致する複数データを削除したいとおもている
のですがうまくいきません。

m_lst.RemoveAt(pos);
のコードに一度入ってしまうと、
ポジションの値がおかしくなってしまうようなのですが...

なにか対策または違う方法はないでしょうか?

while(pos)
{
    Tool = m_lst.GetNext(pos);

    if(Tool != Line)
    {
        m_lst.RemoveAt(pos);
    }
}


Blue  2005-09-15 20:52:25  No: 59029

>    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;
}


επιστημη  2005-09-15 21:19:55  No: 59030

「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
*/


PATIO  2005-09-15 22:25:33  No: 59031

GetTailPositionで最後を取得してGetPrevで遡りながら消す。
GetPrevしてから消せば、大丈夫ではないかな。
これだとずれないと思う。


阪神  2005-09-15 22:25:41  No: 59032

回答ありがとうございました。

>これって、該当の値のPOSITIONでないですよね?
>(posは次の値を指している)

そうでした。
POSITIONがおかしくなってしまったのも
次の値を削除してしまっていたため、
さらにその次の値を見ようとPOSITIONを取得しようとしても
既に削除されている(次の値のPOSITIONは値に付随して保存されている?)
ためだったのだとおもわれます。

>「CListなんか使わない」がもっとも簡単に思えます。
今、PGの不具合修正を行っているため、
安易に変数の型を変更できない状況でした。
今後の参考にさせていただきます。


PATIO  2005-09-15 22:27:53  No: 59033

補足。
削除先のPOSITIONとGetPrevで取得するPOSITIONは別の変数にしておいて
削除が終わったら削除先に取得したものを突っ込めばよろしいかと。
そこまでしなくても大丈夫かもしれないけど。


Blue  2005-09-15 22:33:08  No: 59034

> (次の値の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;
>    };


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加