【问题标题】:How to cycle through smart pointer to a class with custom iterator如何使用自定义迭代器循环通过智能指针指向类
【发布时间】:2021-10-29 14:43:20
【问题描述】:

我有一个指向带有自定义迭代器的类的智能指针。我需要遍历它,但找不到任何示例。

struct SomeContrainer
{
   int a;
}

struct ListClass
{
   std::vector<SomeContrainer>::iterator begin() { return m_devs.begin(); }
   std::vector<SomeContrainer>::iterator end()   { return m_devs.end();   }                                         

   void add( const SomeContrainer& dev ) { m_devs.push_back( dev ); }

   private:
      std::vector<SomeContrainer> m_devs;
};

typedef std::unique_ptr<ListClass> ListPtr_t;


void Foo_Add( const ListPtr_t& list )
{
   SomeContrainer dev1, dev2;
   dev1.a = 10;
   dev2.a = 100;
   list->add(dev1);
   list->add(dev2);
}

void DoSomeWorkOtherList( const ListPtr_t& list )
{
   for( auto const& dev : list )    // <-- how to iterate over list ???
   {}
}

// -----------

ListPtr_t pMyList( new ListClass() );

Foo_Add( pMyList );
DoSomeWorkOtherList(pMyList );

如果我不使用智能指针并且只有一个对象 ListClass list 我正在使用 C++11 并且无法升级,那么它工作正常。

【问题讨论】:

  • 由于没有所有权转让,你的方法应该直接取ListClass:void Foo_Add(ListClass&amp; list)

标签: c++ c++11


【解决方案1】:

你需要取消引用它

void DoSomeWorkOtherList( const ListPtr_t& list ) // void(const unique_ptr<ListClass>&)
{
   for( auto const & dev : *list ) // <-- how to iterate other list ???
   {}
}

对于有问题的代码不是必需的,但您可能还想提供 beginend 的 const 版本。

std::vector<SomeContrainer>::const_iterator begin() const { return m_devs.begin(); }
std::vector<SomeContrainer>::const_iterator end() const { return m_devs.end();   }                                         

【讨论】:

    【解决方案2】:

    您有不同的选择,仅举几例:

    1. 将 const 引用传递给列表。
    void DoSomeWorkOtherList(const ListClass& list)
    {
       std::cout << "v1 (const ListClass&): ";
       for (const auto& dev : list) { std::cout << dev.a << " "; }
       std::cout << "\n";
    }
    
    1. 将 const 原始指针传递给列表。
    void DoSomeWorkOtherList(const ListClass* list)
    {
       std::cout << "v2 (const ListClass*): ";
       if (list)
       {
          for (const auto& dev : *list) { std::cout << dev.a << " "; }
       }
       std::cout << "\n";
    }
    
    1. 将 const 引用传递给指向列表的唯一指针。
    void DoSomeWorkOtherList(const ListPtr_t& list)
    {
       std::cout << "v3 (const ListPtr_t&): ";
       if (list)
       {
          for (const auto& dev : *list) { std::cout << dev.a << " "; }
       }
       std::cout << "\n";
    }
    

    为了确定最适合您的选项,参考 C++ 核心指南会很有帮助。 如果函数代码不暗示所有权更改,一般建议使用指针或引用

    上述情况的可能调用者代码是:

    int main()
    {
        ListPtr_t upl{std::make_unique<ListClass>()};
        upl->add({7});
        upl->add({8});
        DoSomeWorkOtherList(*upl);
        upl->add({9});
        DoSomeWorkOtherList(upl.get());
        Foo_Add(*upl);
        DoSomeWorkOtherList(upl);
    }
    
    // Outputs:
    //     v1 (const ListClass&): 7, 8
    //     v2 (const ListClass*): 7, 8, 9
    //     v3 (const ListPtr_t&): 7, 8, 9, 10, 100
    

    Demo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-17
      • 2016-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多