代码之家  ›  专栏  ›  技术社区  ›  marcman

在基于范围的for循环中,非常量对象的向量似乎被视为常数

  •  0
  • marcman  · 技术社区  · 7 年前

    我有一个 std::vector 通过取消引用填充的对象的数量 std::unique_ptr push_back const 循环中的关键字。下面是演示我所看到的内容的最少代码:

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

    我怀疑这与的移动语义有关 推回 如果调用复制构造函数或其他东西并复制添加的项而不是指向它,迭代器仍在传递相同的副本,不是吗?

    有趣的是,在我的实际代码中,这里由 Item 具有一个成员变量,该变量是 vector unique_ptr .

    2 回复  |  直到 7 年前
        1
  •  4
  •   nefas    7 年前

    当您编写这样的基于范围的for循环时:

    std::vector<int> v = ...;
    for(auto elt : v) {
       ...
    }
    

    的要素 v 被复制到 elt

    在您的示例中,在每个迭代中,您修改 Item 项目 在向量中。

    要解决您的问题,请使用参考资料:

    for (auto& item : _my_vec)
    {
        item.setValue(10);
        std::cout << item.getValue() << std::endl;
    }
    
        2
  •  3
  •   eerorika    7 年前

    非常量对象的向量似乎被视为常数

    如果是的话 视为常数 ,那么编译器会对你大喊大叫,因为写入常量被视为格式错误,编译器会被要求对你大喊大叫。所示代码编译得很好,没有任何警告。

    我猜想你可能指的是,你没有修改向量中的元素。那是因为你修改了 auto item 。该项不是向量的元素,而是向量中该项的副本。你可以 参考 通过使用引用,指向该向量内的项: auto& item item