Исправлено несколько проблем:
Это должно сработать (непроверенный код, я не рядом с компилятором в ближайшие часы)
Обновление
После прибытия домой янаконец-то появился отладчик для отслеживания этого странного поведения (см. комментарии).
К моему ужасу, я обнаружил, что BaseMFCIter
был разработан кем-то с очень ограниченным пониманием того, что итератор является : конструктор копирования и оператор присваивания были совершенно неверными: они создали новый итератор * 1055 - для той же коллекции.Это, однако, означает, что итератор никогда не может быть возвращен из функции.
Поэтому я исправил это (сначала, правильно реализовав его, затем удалив избыточный конструктор и оператор = в пользу компиляторасгенерированные реализации по умолчанию).
git clone git://gist.github.com/1353471.git
- sehe 11 минут назад полагайтесьвместо сгенерированного по умолчанию конструктора и назначения копирования
- sehe 12 минут назад исправлены поврежденные конструктор и назначение копирования
- sehe 65 минут назад ориентировочно
- Dmitry 73 минуты назад Попытка find_if с предикатом
- sehe Heeren 25 часов назад Исправлено и протестировано (VS2010)
- sehe 25 часов назад ( Итератор STL для контейнера MFC CObList )
#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;
}
}