Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6783325
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T16:51:00+00:00 2026-05-26T16:51:00+00:00

I have a working iterator for MFC CObList – BaseMFCIter . It works for

  • 0

I have a working iterator for MFC CObList – BaseMFCIter. It works for iterating in loop but i still didn’t managed to make ListIter to work properly with STL algorithm find_if.
Code

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

    }

gives me foundIter x is: four. This propably happens because of the way the end position is defined so

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

doesn’t iterate properly but i can’t figure out how to fix it.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T16:51:01+00:00Added an answer on May 26, 2026 at 4:51 pm

    A number of issues fixed:

    • (bool) lhs->x.compare( stringToCompare ) returns true _whenever the string don’t match** (see string::compare)
    • you were searching for “1”, which doesn’t exist
    • since the predicate was wrong, you received the first match, which was the first element, also inserted the last, and the name was "four" 🙂
    • you didn’t check whether a valid match was found (dereferencing the end-iterator is illegal and may crash your program or do worse things: undefined behaviour)
    • you had a superflous x.c_str() in the output statement
    • I changed the Compare predicate around to be more idiomatic:

      • initialize stringToCompare from the constructor
      • make the field const
      • make the operator() a const method

    This should do the trick (untested code, I’m not near a compiler the coming hours)

    Update

    After arriving home, I finally broke out the debugger to track that strange behaviour (see comments).

    To my dismay, I found out that the BaseMFCIter was designed by someone with very limited understanding of what an iterator is: the copy constructor and assignment operator were completely wrong: they had the effect of creating a new begin iterator – for the same collection. This however, means that an iterator could never be returned from a function.

    Therefore, I fixed it (first by implementing it right, later by removing the now-redundant constructor and operator= in favour of the compiler-generated default implementations).

    See the full history of my and your edits:

    git clone git://gist.github.com/1353471.git
    
    • sehe 11 minutes ago rely on default generated copy constructor and assignment instead
    • sehe 12 minutes ago fixed broken copy constructor and assignment
    • sehe 65 minutes ago tentative
    • Dmitry 73 minutes ago Attempt at find_if with predicate
    • sehe Heeren 25 hours ago Fixed and Tested (VS2010)
    • sehe 25 hours ago ( STL iterator for MFC container 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;
        }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have been working with relational databases for sometime, but it only recently occurred
I am working with Vaadin and I have some trouble iterating through choices in
So I have this loop in my code that needs two separately working Iterators.
I have been working on a web services related project for about the last
I have been working with Visual Studio (WinForm and ASP.NET applications using mostly C#)
I have been working with a string[] array in C# that gets returned from
We have been working with CVS for years, and frequently find it useful to
I have been working on some legacy C++ code that uses variable length structures
I have a working copy of my project, checked out using Subversion 1.5.1. When
I have a working LINQ to SQL model. I want to be able to

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.