MFC 容器 CObList 的 STL 迭代器
我有一个 Folder 类,其中包含 Folders 和 Files 两个列表。
class Folder : public CObject
{
public:
typedef std::string StringT;
...
Container filesInFolder;
Container foldersInFolder;
StringT folderName;
...
};
class File : public CObject { ... };
列表源自 CObList。 类容器:公共CObList
。我需要在 foldersInFolder 中按名称执行搜索,在 filesInFolder 中按名称和扩展名执行搜索。 CObList::Find 不允许我使用谓词。我通常会使用 std::find_if 和谓词:
struct Comparator
{
Folder::StringT stringToCompare;
bool operator() ( const Folder* lhs )
{
return lhs->GetFolderName( ) == stringToCompare;
}
};
所以我需要一个迭代器来使用这个函数。在 [codeguru] 上,他们定义了一个类 BaseMFCIter][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();
}
};
但是如果我定义自己的 ListIter 类,其中 myCObject 是文件或文件夹。
class ListIter : public BaseMFCIter < myCObject, CObList >
{
public:
ListIter( CObList* pObj = 0) : BaseMFCIter< myCObject, CObList >
(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'
是否有针对重载函数问题的解决方法?如果 MFC 集合有 std::find_if 的类似物,请告诉我。
I have a Folder class which contains two lists of Folders and Files.
class Folder : public CObject
{
public:
typedef std::string StringT;
...
Container filesInFolder;
Container foldersInFolder;
StringT folderName;
...
};
class File : public CObject { ... };
Lists derive from CObList. Class Container : public CObList
. I need to perform search inside foldersInFolder by name and in filesInFolder by name and extension. CObList::Find does not allow me to use predicates. I would normaly use std::find_if with predicate:
struct Comparator
{
Folder::StringT stringToCompare;
bool operator() ( const Folder* lhs )
{
return lhs->GetFolderName( ) == stringToCompare;
}
};
So i need an iterator to use this function. On [codeguru they define a class BaseMFCIter][1] which is a child of 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();
}
};
But if i define my own ListIter class with myCObject being File or Folder.
class ListIter : public BaseMFCIter < myCObject, CObList >
{
public:
ListIter( CObList* pObj = 0) : BaseMFCIter< myCObject, CObList >
(pObj, &CObList::GetHeadPosition, &CObList::GetNext )
{}
};
it leads me to compiler error:
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'
Is there a workaround for this problem with overloaded function? If there is an analogue of std::find_if for MFC collections, please tell me.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是基于您提供的测试源的完整工作固定示例:
下载链接:
这是相关的(更改)代码 和测试输出
输出:
如你所见,我
使用strongtyped访问器扩展了
Container
派生类(todo:您可能需要添加其他CObList:: *
接口成员,例如GetAt(...)
)修复了
的实例化BaseMFCIter
模板来自至
main
中包含了一个 STL 标准样式循环,以演示它的工作原理。 p>Here is a complete working fixed example based on your supplied test source:
Download links:
Here is the relevant (changed) code and test output
The output:
As you can see I
Extended the
Container
derived class with strongtyped accessors (todo: you may want to add otherCObList::*
interface members, such asGetAt(...)
)fixed the instantiation of
BaseMFCIter
template fromto
Included an STL-standard style loop to
main
to demo that it works.