Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to change a container elements in another 'temporary' container

I have a temporary list that needs to change its elements and erase() them from the list as a way of marking them as done.

std::list<Vertex> temp {vertices.begin(), vertices.end()};

I’ve tried using Vertex& and Vertex* without success, and the second one makes the code very messy.

What is the proper way to do this? Thanks in advance

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Edit: surrounding code

    int label = 1;
    // change elements without affecting temporary list
    std::list<Vertex*> unlabeledVertices {graph.vertices.begin(), graph.vertices.end()};

    for (auto iter = unlabeledVertices.begin(); iter != unlabeledVertices.end(); ++label) {
        (*iter)->label = label;

        // temporary list
        std::list<Vertex*> currentLabelVertices;
        currentLabelVertices.push_back(*iter);

        // check if we can label any other vertex with the current color
        auto nestedIter = iter;
        for (nestedIter++; nestedIter != unlabeledVertices.end(); ) {
            // checking current vertex against any other colored vertex
            if (std::none_of(currentLabelVertices.begin(), currentLabelVertices.end(),
                [=](const Vertex* v){ return (*nestedIter)->isConnected(*v); })) {
                (*nestedIter)->label = label;
                currentLabelVertices.push_back(*nestedIter);

                nestedIter = unlabeledVertices.erase(nestedIter);
            }
            else {
                nestedIter++;
            }
        }

        iter = unlabeledVertices.erase(iter);
    }

Error message:

/usr/bin/g++ -fdiagnostics-color=always -g /home/etzl/projects/c-cpp/test/*.cc -o exec
In file included from /usr/include/x86_64-linux-gnu/c++/10/bits/c++allocator.h:33,
                 from /usr/include/c++/10/bits/allocator.h:46,
                 from /usr/include/c++/10/string:41,
                 from /usr/include/c++/10/bits/locale_classes.h:40,
                 from /usr/include/c++/10/bits/ios_base.h:41,
                 from /usr/include/c++/10/ios:42,
                 from /usr/include/c++/10/ostream:38,
                 from /usr/include/c++/10/iostream:39,
                 from /home/etzl/projects/c-cpp/test/main.cc:1:
/usr/include/c++/10/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = Vertex*; _Args = {Vertex&}; _Tp = std::_List_node<Vertex*>]’:
/usr/include/c++/10/bits/alloc_traits.h:512:17:   required from ‘static void std::allocator_traits<std::allocator<_CharT> >::construct(std::allocator_traits<std::allocator<_CharT> >::allocator_type&, _Up*, _Args&& ...) [with _Up = Vertex*; _Args = {Vertex&}; _Tp = std::_List_node<Vertex*>; std::allocator_traits<std::allocator<_CharT> >::allocator_type = std::allocator<std::_List_node<Vertex*> >]’
/usr/include/c++/10/bits/stl_list.h:637:33:   required from ‘std::__cxx11::list<_Tp, _Alloc>::_Node* std::__cxx11::list<_Tp, _Alloc>::_M_create_node(_Args&& ...) [with _Args = {Vertex&}; _Tp = Vertex*; _Alloc = std::allocator<Vertex*>; std::__cxx11::list<_Tp, _Alloc>::_Node = std::__cxx11::list<Vertex*>::_Node]’
/usr/include/c++/10/bits/stl_list.h:1911:32:   required from ‘void std::__cxx11::list<_Tp, _Alloc>::_M_insert(std::__cxx11::list<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {Vertex&}; _Tp = Vertex*; _Alloc = std::allocator<Vertex*>; std::__cxx11::list<_Tp, _Alloc>::iterator = std::__cxx11::list<Vertex*>::iterator]’
/usr/include/c++/10/bits/stl_list.h:1227:19:   required from ‘void std::__cxx11::list<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {Vertex&}; _Tp = Vertex*; _Alloc = std::allocator<Vertex*>]’
/usr/include/c++/10/bits/stl_list.h:1840:18:   required from ‘void std::__cxx11::list<_Tp, _Alloc>::_M_initialize_dispatch(_InputIterator, _InputIterator, std::__false_type) [with _InputIterator = std::_List_iterator<Vertex>; _Tp = Vertex*; _Alloc = std::allocator<Vertex*>]’
/usr/include/c++/10/bits/stl_list.h:806:26:   required from ‘std::__cxx11::list<_Tp, _Alloc>::list(_InputIterator, _InputIterator, const allocator_type&) [with _InputIterator = std::_List_iterator<Vertex>; <template-parameter-2-2> = void; _Tp = Vertex*; _Alloc = std::allocator<Vertex*>; std::__cxx11::list<_Tp, _Alloc>::allocator_type = std::allocator<Vertex*>]’
/home/etzl/projects/c-cpp/test/main.cc:58:87:   required from here
/usr/include/c++/10/ext/new_allocator.h:150:4: error: cannot convert ‘Vertex’ to ‘Vertex*’ in initialization
  150 |  { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
      |    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Build finished with error(s)

>Solution :

You should use std::unordered_set<Vertex*> currentLabelVertices instead of a list. It gives O(1) lookup instead of the O(n) solution you have with std::none_of().

Your other problem is here:

std::list<Vertex*> unlabeledVertices {graph.vertices.begin(), graph.vertices.end()};

It doesn’t compile because graph.vertices contains Vertex instances, not pointers. The fix is simple:

std::list<Vertex*> unlabeledVertices;
for (auto& vertex : graph.vertices)
    unlabeledVertices.push_back(&vertex);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading