vendredi 21 juillet 2017

Vector of non-const objects seems to be treated as constant in range-based for loop

I have a std::vector of objects being filled by de-referencing std::unique_ptr's in the push_back calls. However, when I run through a mutable range-based for-loop, my modification to these objects stays local to the loop. In other words, it seems as those objects are being treated as constant, despite that lack of a const keyword in the loop. Here is minimal code to demonstrate what I'm seeing:

#include <vector>
#include <memory>
#include <iostream>

class Item
{
    public:
        typedef std::unique_ptr<Item> unique_ptr;

        inline static Item::unique_ptr createItem()
        {
            return std::unique_ptr<Item>(new Item());
        }

        inline const int getValue() const { return _value; }
        inline void setValue(const int val) { _value = val; }

    private:
        int _value;
};

int main()
{
    std::vector<Item> _my_vec;
    for (int i = 0; i < 5; i++)
    {
        Item::unique_ptr item = Item::createItem();
        _my_vec.push_back(*item);
    }

    for (auto item : _my_vec)
    {
        // modify item (default value was 0)
        item.setValue(10);

        // Correctly prints 10
        std::cout << item.getValue() << std::endl;
    }


    for (auto item : _my_vec)
    {
        // Incorrectly prints 0's (default value)
        std::cout << item.getValue() << std::endl;
    }

}

I suspect this has something to do with the move semantics of std::unique_ptr? But that wouldn't quite make sense because even if push_back is calling the copy constructor or something and copying the added item rather than pointing to it, the iterator is still passing over the same copies, no?

Interestingly enough, in my actual code, I have a vector of shared pointers to another class, and modifications to the objects being pointed to by those shared pointers persist between loops. This is why I suspect there's something funky with the unique_ptr.

Can anyone explain this behavior and explain how I may fix this issue while still using pointers?

Aucun commentaire:

Enregistrer un commentaire