Collections 使用从std::iterator派生的迭代器在MFC容器中查找_if
我有一个用于MFC的CObList-Collections 使用从std::iterator派生的迭代器在MFC容器中查找_if,collections,stl,mfc,iterator,c++,Collections,Stl,Mfc,Iterator,C++,我有一个用于MFC的CObList-BaseMFCIter。它适用于循环中的迭代,但我仍然无法使ListIter与STL算法find\u if正常工作。 代码 没有正确地迭代,但我不知道如何修复它。修复了许多问题: (bool)lhs->x.compare(stringToCompare)在字符串不匹配时返回true(请参阅) 您正在搜索“1”,但它不存在 由于谓词错误,您收到了第一个匹配项,即第一个元素,也插入了最后一个元素,名称为“four”:) 您没有检查是否找到了有效的匹配项(取消引用
BaseMFCIter
。它适用于循环中的迭代,但我仍然无法使ListIter
与STL算法find\u if正常工作。
代码
没有正确地迭代,但我不知道如何修复它。修复了许多问题:
在字符串不匹配时返回true(请参阅)(bool)lhs->x.compare(stringToCompare)
- 您正在搜索“1”,但它不存在
- 由于谓词错误,您收到了第一个匹配项,即第一个元素,也插入了最后一个元素,名称为
:)“four”
- 您没有检查是否找到了有效的匹配项(取消引用结束迭代器是非法的,可能会导致程序崩溃或出现更糟糕的情况:未定义的行为)
- 在输出语句中有一个superflous
x.c_str()
- 我将
谓词更改为更加惯用:Compare
- 从构造函数初始化
stringToCompare
- 使字段
const
- 使
操作符()成为
常量
方法
- 从构造函数初始化
BaseMFCIter
是由对迭代器的理解非常有限的人设计的:复制构造函数和赋值运算符完全错误:它们产生了为同一集合创建新的begin
迭代器的效果。然而,这意味着迭代器永远无法从函数返回
因此,我修复了它(首先通过正确实现它,然后通过删除现在冗余的构造函数和运算符=来支持编译器生成的默认实现)
见:
- 11分钟前的sehe依赖于默认生成的复制构造函数和赋值
- sehe 12分钟前修复了损坏的副本构造函数和赋值
- 65分钟前的塞赫
- Dmitry 73分钟前尝试使用谓词查找_if
- sehe Heeren 25小时前修复并测试(VS2010)
- 25小时前()
#包括“afxwin.h”
#包括“afxtempl.h”
#包括
#包括
#包括
#包括
#包括
类myObject:公共对象
{
公众:
myObject(const std::string&val){x=val;}
std::字符串x;
};
模板
类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();}
布尔运算符==(常量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();
}
};
结构容器:公共CObList
{
MyObject*GetNext(位置和位置)
{
返回动态_cast(CObList::GetNext(rPosition));
}
MyObject常量*GetNext(位置和位置)常量
{
返回动态_cast(CObList::GetNext(rPosition));
}
};
类列表项:public-basemCiter
{
公众:
ListItemer(容器*pObj=0)
:BaseMFCIter
(pObj,&CObList::GetHeadPosition,&Container::GetNext)
{
}
};
结构比较器
{
比较器(const std::string和compareTo):stringToCompare(compareTo){
布尔运算符()(常量myobject*lhs)常量
{
返回0==lhs->x.compare(stringToCompare);
}
私人:
常量std::字符串stringToCompare;
};
空干管()
{
MyObject*m=新的MyObject(“一”);
MyObject*n=新的MyObject(“两个”);
MyObject*p=新的MyObject(“三”);
MyObject*q=新的MyObject(“四”);
集装箱运输;
续加水头(m);
续地址(n);
#include < iterator >
#include "afxwin.h"
#include "afxtempl.h"
#include <iostream>
#include <algorithm>
#include <cstdlib>
class myCObject : public CObject
{
public:
myCObject( std::string val )
{
x = val;
}
std::string x;
};
template < typename 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();
}
};
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)
{
}
};
struct Comparator
{
std::string stringToCompare;
bool operator() ( const myCObject* lhs )
{
return (bool) lhs->x.compare( stringToCompare );
}
};
void main( )
{
myCObject* m = new myCObject( "one" );
myCObject* n = new myCObject( "two" );
myCObject* p = new myCObject( "three" );
myCObject* q = new myCObject( "four" );
Container cont;
cont.AddHead( m );
cont.AddHead( n );
cont.AddHead( p );
cont.AddHead( q );
Comparator pred;
pred.stringToCompare = "1";
ListIter iter = ListIter( &cont );
ListIter endIter = ListIter( );
ListIter foundIter = std::find_if( iter, endIter, pred );
std::cout << "foundIter x is: " << foundIter->x.c_str() << std::endl;
}
_InIt _Find_if(_InIt _First, _InIt _Last, _Pr _Pred)
{ // find first satisfying _Pred
_DEBUG_RANGE(_First, _Last);
_DEBUG_POINTER(_Pred);
for (; _First != _Last; ++_First)
if (_Pred(*_First))
break;
return (_First);
}
git clone git://gist.github.com/1353471.git
#include "afxwin.h"
#include "afxtempl.h"
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <string>
#include <iterator>
class myCObject : public CObject
{
public:
myCObject( const std::string& val ) { x = val; }
std::string x;
};
template < typename 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(); }
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();
}
};
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)
{
}
};
struct Comparator
{
Comparator(const std::string& compareTo) : stringToCompare(compareTo) {}
bool operator() ( const myCObject* lhs ) const
{
return 0 == lhs->x.compare( stringToCompare );
}
private:
const std::string stringToCompare;
};
void main( )
{
myCObject* m = new myCObject( "one" );
myCObject* n = new myCObject( "two" );
myCObject* p = new myCObject( "three" );
myCObject* q = new myCObject( "four" );
Container cont;
cont.AddHead( m );
cont.AddHead( n );
cont.AddHead( p );
cont.AddHead( q );
Comparator pred("three");
ListIter iter = ListIter(&cont),
endIter = ListIter( );
ListIter foundIter = std::find_if( iter, endIter, pred );
if (endIter != foundIter)
{
std::cout << "foundIter x is: " << foundIter->x << std::endl;
}
else
{
std::cout << "not found" << std::endl;
}
}