Search code examples
c++c++11setunique-ptrdeleted-functions

using range-based for with std::set<std::unique_ptr<T>> deleted function


I'm trying to use a range based iterator with a set of unique_ptr instances but I'm getting the following compilation error:

C2280: 'std::unique_ptr<Component,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)' : attempting to reference a deleted function

The basics of the code is below:

#include <set>
#include <memory>

std::set<std::unique_ptr<Component>>* m_components;

class Component
{
    void DoSomething(){};
};

void ProcessComponents()
{
    for (auto componentsIterator : *m_components)

    {
        componentsIterator->DoSomething();
        componentsIterator++;
    }
}

Any idea why this would be a problem or how to solve it?


Solution

  • for (auto componentsIterator : *m_components)
    

    That auto expands to std::unique_ptr<Component>, which means that you are trying to take a copy of each element. IOW, that loop actually is:

    for(auto it=m_components->begin(); it!=m_components->end(); ++it)
    {
        std::unique_ptr<Component> componentsIterator=*it;
        componentsIterator->DoSomething();
        componentsIterator++;
    }
    

    As you can see, you are invoking std::unique_ptr<Component> copy constructor, but the copy constructor of unique_ptr is deleted (because it is against the unique_ptr semantic).

    Use auto & to take a reference instead.

    (BTW, componentsIterator there is not a sensible name, since it's not an iterator, it's the actual element)