C++ MFC容器列表的STL迭代器

C++ MFC容器列表的STL迭代器,c++,stl,mfc,iterator,function-pointers,C++,Stl,Mfc,Iterator,Function Pointers,我有一个文件夹类,它包含两个文件夹和文件列表 列表源于CObList类容器:公共CObList。我需要在foldersInFolder中按名称执行搜索,在FileInfolder中按名称和扩展名执行搜索。CObList::Find不允许我使用谓词。我通常将std::find_与谓词一起使用: struct Comparator { Folder::StringT stringToCompare; bool operator() ( const Folder* lhs )

我有一个文件夹类,它包含两个文件夹和文件列表

列表源于CObList<代码>类容器:公共CObList。我需要在foldersInFolder中按名称执行搜索,在FileInfolder中按名称和扩展名执行搜索。CObList::Find不允许我使用谓词。我通常将std::find_与谓词一起使用:

struct Comparator
{
    Folder::StringT stringToCompare;
    bool operator() ( const Folder* lhs )
    {
        return lhs->GetFolderName( ) == stringToCompare;
    }
};
所以我需要一个迭代器来使用这个函数。在[codeguru]上,他们定义了一个类basemCiter][1],它是std::iterator的子类:

#include < iterator >

// Define BaseMFCIter as a standard input iterator.
//
// The template arguments are: 
//  Item: the contained element type
//  Cont: the container type
//  Key:  the access key (defaults to POSITION)

template < class Item, class Cont, class Key = POSITION >
class BaseMFCIter : public std::iterator < std::input_iterator_tag, Item >
{
public:
   // Define types for the 2 member functions to be used:
   typedef Key  (Cont::*GetFirstFunctionPtr) ()     const;
   typedef Item (Cont::*GetNextFunctionPtr)  (Key&) const;

   // Default constructor, makes a null iterator, equal to BaseMFCIter::end()
   BaseMFCIter() : m_pCont(0), m_Pos(0), m_GetFirstFunc(0), m_GetNextFunc(0), m_End(true) {}

   // Constructor taking pointer to container and the iteration functions
   BaseMFCIter(Cont* pCont, GetFirstFunctionPtr pFF, GetNextFunctionPtr pNF) 
      : m_pCont(pCont), m_Pos(0), m_GetFirstFunc(pFF), m_GetNextFunc(pNF)
   { init(); }

   // Copy constructor, initialises iterator to first element
   BaseMFCIter(const BaseMFCIter& vi) : m_pCont(vi.m_pCont), m_Pos(0),
    m_GetFirstFunc(vi.m_GetFirstFunc), m_GetNextFunc(vi.m_GetNextFunc)
   { init(); }

   // Assignment operator, initialises iterator to first element
   BaseMFCIter& operator=(const BaseMFCIter& vi)
   {
      m_pCont       = vi.m_pCont; 
      m_GetFirstFunc    = vi.m_GetFirstFunc;
      m_GetNextFunc = vi.m_GetNextFunc;
      init();  
      return *this; 
   }

   bool operator == (const BaseMFCIter& rhs) const
   { return (m_Pos == rhs.m_Pos && m_End == rhs.m_End); }

   bool operator != (const BaseMFCIter& rhs) const 
   { return !operator==(rhs); }

   BaseMFCIter& operator ++ ()    { advance(); return *this; }
   BaseMFCIter& operator ++ (int) { BaseMFCIter ret(*this); advance(); return ret; }
   Item         operator *  ()    { return m_Item; }
   Item         operator -> ()    { return m_Item; }

   static BaseMFCIter end   ()    { return BaseMFCIter(); } // end() returns default null iterator

private:
   Item  m_Item;      // Current item from container
   Cont* m_pCont;     // Pointer to container
   Key   m_Pos;       // Key to item in container
   bool  m_End;       // Flag to indicate end of container reached

   // Pointers to container iteration functions
   GetFirstFunctionPtr m_GetFirstFunc;
   GetNextFunctionPtr  m_GetNextFunc;

   // Use container GetFirst & GetNext functions to set to first element, or end() if not found
   void init() 
   {
      m_Pos = 0;
      m_End = true;

      if (m_pCont && m_GetFirstFunc != 0)
      {
         m_Pos = (m_pCont->*m_GetFirstFunc)();
         advance();
      }
   }

   // Use container GetNext function to find next element in container
   void advance()
   {
      m_End = m_Pos ? false : true;
      m_Item = (m_Pos && m_pCont && m_GetNextFunc != 0) ? 
               (m_pCont->*m_GetNextFunc)(m_Pos) : Item();
   }
};
#包括
//将BaseMCiter定义为标准输入迭代器。
//
//模板参数包括:
//项:包含的元素类型
//Cont:容器类型
//键:访问键(默认为位置)
模板<类别项目,类别控制,类别键=位置>
类BaseMFCIter:public std::iterator
{
公众:
//定义要使用的2个成员函数的类型:
typedef键(Cont::*GetFirstFunctionPtr)()常量;
typedef项(续::*GetNextFunctionPtr)(键和)常量;
//默认构造函数,生成一个空迭代器,等于BaseMFCIter::end()
BaseMFCIter():m_pCont(0),m_Pos(0),m_GetFirstFunc(0),m_GetNextFunc(0),m_End(true){}
//使用指向容器和迭代函数的指针的构造函数
BaseMFCIter(续*pCont、GetFirstFunctionPtr pFF、GetNextFunctionPtr pNF)
:m_pCont(pCont)、m_Pos(0)、m_GetFirstFunc(pFF)、m_GetNextFunc(pNF)
{init();}
//复制构造函数,初始化迭代器到第一个元素
BaseMfcitter(const BaseMfcitter&vi):m_pCont(vi.m_pCont),m_Pos(0),
m_GetFirstFunc(vi.m_GetFirstFunc)、m_GetNextFunc(vi.m_GetNextFunc)
{init();}
//赋值运算符,初始化迭代器到第一个元素
BaseMFCIter和运算符=(常量BaseMFCIter和vi)
{
m_pCont=vi.m_pCont;
m_GetFirstFunc=vi.m_GetFirstFunc;
m_GetNextFunc=vi.m_GetNextFunc;
init();
归还*这个;
}
布尔运算符==(常量BaseMFCIter和rhs)常量
{return(m_Pos==rhs.m_Pos&&m_End==rhs.m_End)}
布尔运算符!=(常量BaseMFCIter和rhs)常量
{return!运算符==(rhs);}
BaseMFCIter&operator++(){advance();返回*this;}
BaseMFCIter&operator++(int){BaseMFCIter-ret(*this);advance();return-ret;}
项运算符*(){return m_Item;}
项运算符->(){return m_Item;}
静态BaseMFCIter end(){return BaseMFCIter();}//end()返回默认的空迭代器
私人:
Item m_Item;//容器中的当前项
Cont*m_pCont;//指向容器的指针
Key m_Pos;//容器中项目的键
bool m_End;//表示已到达容器末尾的标志
//指向容器迭代函数的指针
GetFirstFunction PTR m_GetFirstFunc;
GetNextFunction PTR m_GetNextFunc;
//使用容器GetFirst和GetNext函数设置为第一个元素,如果找不到,则设置为end()
void init()
{
m_Pos=0;
m_End=真;
if(m_pCont&&m_GetFirstFunc!=0)
{
m_Pos=(m_pCont->*m_GetFirstFunc)();
前进();
}
}
//使用container GetNext函数查找容器中的下一个元素
作废预付款()
{
m_End=m_Pos?false:true;
m_Item=(m_Pos和m_pCont和m_GetNextFunc!=0)?
(m_pCont->*m_GetNextFunc)(m_Pos):Item();
}
};
但如果我定义自己的ListItemer类,myObject是File或Folder

class ListIter : public BaseMFCIter < myCObject, CObList  >
{
public:
   ListIter( CObList* pObj = 0) : BaseMFCIter< myCObject, CObList >
       (pObj, &CObList::GetHeadPosition, &CObList::GetNext )
   {}
};
class列表项:public-basemCiter
{
公众:
ListIter(CObList*pObj=0):BaseMFCIter
(pObj,&CObList::GetHeadPosition,&CObList::GetNext)
{}
};
这会导致编译器错误:

Error   1   error C2664: 'BaseMFCIter<Item,Cont>::BaseMFCIter(Cont *,__POSITION (__thiscall CObList::* )(void) const,myCObject (__thiscall CObList::* )(Key &) const)' : cannot convert parameter 3 from 'overloaded-function' to 'myCObject (__thiscall CObList::* )(Key &) const'
Error 1 Error C2664:'BaseMFCIter::BaseMFCIter(Cont*,'u位置('u thiscall CObList::*)(void)const,myobject('u thiscall CObList::*)(Key&)const)':无法将参数3从“重载函数”转换为“myobject('u thiscall CObList::*)(Key&)const”

对于这个重载函数的问题,有解决方法吗?如果有类似于std::find_If的MFC集合,请告诉我

以下是一个基于您提供的测试源的完整工作修复的示例:

下载链接:

以下是相关(更改)代码和测试输出

struct Container : public CObList
{
    myCObject* GetNext(POSITION& rPosition)       
    {
        return dynamic_cast<myCObject*>(CObList::GetNext(rPosition)); 
    }
    myCObject const* GetNext(POSITION& rPosition) const 
    {
        return dynamic_cast<const myCObject*>(CObList::GetNext(rPosition));
    }
};


class ListIter : public BaseMFCIter < const myCObject*, Container, POSITION  >
{
public:
    ListIter( Container* pObj = 0)  
        : BaseMFCIter< const myCObject*, Container, POSITION >
            (pObj, &CObList::GetHeadPosition, &Container::GetNext)
    {
    }
};

void main( )
{
    myCObject* m = new myCObject( 1 );
    myCObject* n = new myCObject( 2 );
    myCObject* p = new myCObject( 3 );
    myCObject* q = new myCObject( 4 );

    Container cont;
    cont.AddHead( m );
    cont.AddHead( n );
    cont.AddHead( p );
    cont.AddHead( q );

    POSITION pos = cont.GetHeadPosition( );

    while (pos != NULL)
    {
        const myCObject& item = *cont.GetNext( pos );
        std::cout << "Oldfashioned: " << item.x << std::endl;
    }

    for (ListIter it=ListIter(&cont); it!= ListIter(); ++it)
    {
        std::cout << "Newfangled: " << it->x << std::endl;
    }
}
如你所见,我

  • 使用strong类型的访问器扩展了
    容器
    派生类(todo:您可能需要添加其他
    CObList:*
    接口成员,例如
    GetAt(…)

  • 修复了来自的
    BaseMFCIter
    模板的实例化

     BaseMFCIter < myCObject, Container, POSITION  >
    
    BaseMFCIter
    

    BaseMFCIter
    
  • 包括一个STL标准样式的循环到
    main
    ,以演示它的工作原理


谢谢,这对迭代有效,但我仍然找不到解决算法问题的方法(请参见UPD)。@Dmitry:你能接受这一点,然后开始另一个问题吗?这个问题需要跟踪的工作量相当大,你不可能在一个问题中完成整个项目:)@Dmitry干杯,欢迎来到SO!完成-
Oldfashioned: 4
Oldfashioned: 3
Oldfashioned: 2
Oldfashioned: 1
Newfangled: 4
Newfangled: 3
Newfangled: 2
Newfangled: 1
 BaseMFCIter < myCObject, Container, POSITION  >
 BaseMFCIter < const myCObject*, Container, POSITION  >