CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7
  1. #1
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Iterator initialization problem...

    This code apparently compiles with gcc but is giving me a compiler error with MSVC:-

    Code:
    namespace {
    struct id_compare
    {
    	bool operator()(const boost::shared_ptr<Playlist>& p1, const boost::shared_ptr<Playlist>& p2)
    	{
    		return p1->id () < p2->id ();
    	}
    };
    
    typedef std::set<boost::shared_ptr<Playlist> > List;
    typedef std::set<boost::shared_ptr<Playlist>, id_compare> IDSortedList;
    
    static void
    get_id_sorted_playlists (const List& playlists, IDSortedList& id_sorted_playlists)
    {
    	for (List::const_iterator i = playlists.begin(); i != playlists.end(); ++i) {
    		id_sorted_playlists.insert(*i);
    	}
    }
    
    } // anonymous namespace
    
    void
    SessionPlaylists::add_state (XMLNode* node, bool full_state)
    {
    	IDSortedList id_sorted_playlists;
    	get_id_sorted_playlists (playlists, id_sorted_playlists);
    
    	List::iterator i = id_sorted_playlists.begin (); // <--- ERROR HERE !!
    
    	// Do some stuff
    }
    I see this error at the indicated line:-

    Code:
    error C2440: 'initializing' : cannot convert from 'std::_Tree<_Traits>::iterator' to 'std::_Tree<_Traits>::iterator'
            with
            [
                _Traits=std::_Tset_traits<boost::shared_ptr<ARDOUR::Playlist>,`anonymous-namespace'::id_compare,std::allocator<boost::shared_ptr<ARDOUR::Playlist>>,false>
            ]
            and
            [
                _Traits=std::_Tset_traits<boost::shared_ptr<ARDOUR::Playlist>,std::less<boost::shared_ptr<ARDOUR::Playlist>>,std::allocator<boost::shared_ptr<ARDOUR::Playlist>>,false>
            ]
    
            No constructor could take the source type, or constructor overload resolution was ambiguous
    Can anyone explain what's wrong here..?
    Last edited by VictorN; October 10th, 2016 at 10:54 AM. Reason: Replaced the Quote tags with the code ones to shorten the width
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  2. #2
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: Iterator initialization problem...

    Taking id_compare out of the equation seems to make it compile - i.e. if I declare IdSortedList like this:-

    Code:
    typedef std::set<boost::shared_ptr<Playlist> > IDSortedList;
    I visited MSDN and realised that for std::set, VS2013 has a lot more c'tors than VS2005 which I'm using. So is this maybe a C++11 extension or something like that?
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  3. #3
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,825

    Re: Iterator initialization problem...

    For
    Code:
    List::iterator i = id_sorted_playlists.begin (); // <--- ERROR HERE !!
    try
    Code:
    IDSortedList::iterator i = id_sorted_playlists.begin (); // <--- ERROR HERE !!
    This is where auto type comes in handy!
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  4. #4
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: Iterator initialization problem...

    Thanks 2kaud, you just beat me to it. I literally figured it out about 10 seconds ago !!

    Interesting (again...) that it compiles with gcc !
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  5. #5
    Join Date
    Oct 2008
    Posts
    1,456

    Re: Iterator initialization problem...

    Quote Originally Posted by John E View Post
    Interesting (again...) that it compiles with gcc !
    this is an example of a SCARY iterator assignment ( see this paper for example ), it's always been perfectly legal for a compiler to not diagnose such cases because iterators of different containers have never been required to be different types under the hood.

    That said, gcc behaviour is explicitly allowed since c++11, and it may be standardized as required in the future.

  6. #6
    John E is offline Elite Member Power Poster
    Join Date
    Apr 2001
    Location
    Manchester, England
    Posts
    4,835

    Re: Iterator initialization problem...

    Thanks Superbonzo. Just out of curiosity...

    What would be the advantage of using an iterator that's different from the type of objects being iterated? e.g. in this case, using List::iterator to iterate over objects of type IDSortedList? I guess one advantage is that it might facilitate different sorting methods (i.e. different criteria for deciding greater than / less than). Any other advantages?
    "A problem well stated is a problem half solved.” - Charles F. Kettering

  7. #7
    Join Date
    Oct 2008
    Posts
    1,456

    Re: Iterator initialization problem...

    the idea behind scary iterators is general.

    Consider a class template foo<T1,T2,...> and a member type foo<...>::bar_type

    now, the claim behind the SCARY iterator proposal is that whenever some Ti is conceptually indipendent from bar_type, then the latter should not change whenever the former changes, type wise.
    why, correctness aside ? because in this way you can exploit static polymorphism and pass around bar_type's instances coming from possibly different foo<>'s without harm ( for the aforementioned reasons) nor performance penalty ( you'd need dynamic polymorphism otherwise ).

    In the container case, a container iterator serves two purposes, it gives a view of some container element ( via dereferencing ) and provides a way to step to its neighbours ( via incrementing ); both operations are independent from things like allocators, comparators, etc... and hence should not depend on them ( of course, comparators do influence the way elements are iterated, but this is not a responsability of the iterator, but of the container accessors that commit them ).

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured