what is the preferred way to expose custom STL-style iteration?

前端 未结 4 1918
春和景丽
春和景丽 2020-12-19 04:47

(also see Is there a good way not to hand-write all twelve required Container functions for a custom type in C++? )


For a class such as

namespa         


        
4条回答
  •  南笙
    南笙 (楼主)
    2020-12-19 05:21

    I suggest creating both sets of functions -- member functions as well as non-member functions -- to allow for maximum flexibility.

    namespace JDanielSmith {
       class C
       {
          const size_t _size;
          const std::unique_ptr _data;
    
          public:
          C(size_t size) : _size(size), _data(new int[size]) {}
    
          inline const int* get() const { return _data.get(); }
          inline int* get() { return _data.get(); }
    
          size_t size() const { return _size; }
    
          int* begin() { return get(); }
          int* end() { return get() + _size; }
          const int* begin() const { return get(); }
          const int* end() const { return get() + _size; }
          const int* cbegin() const { return get(); }
          const int* cend() const { return get() + _size; }
    
       };
    
       int* begin(C& c) { return c.begin(); }
       int* end(C& c) { return c.end(); }
       const int* begin(C const& c) { return c.begin(); }
       const int* end(C const& c) { return c.end(); }
       const int* cbegin(C const& c) { return c.begin(); }
       const int* cend(C const& c) { return c.end(); }
    }
    

    The member functions are necessary if you want to be able to use objects of type C as arguments to std::begin, std::end, std::cbegin, and std::cend.

    The non-member functions are necessary if you want to be able to use objects of type C as arguments to just begin, end, cbegin, and cend. ADL will make sure that the non-member functions will be found for such usages.

    int main()
    {
       JDanielSmith::C c1(10);
    
       {
          // Non-const member functions are found
          auto b = std::begin(c1);
          auto e = std::end(c1);
          for (int i = 0; b != e; ++b, ++i )
          {
             *b = i*10;
          }
       }
    
       JDanielSmith::C const& c2 = c1;
       {
          // Const member functions are found
          auto b = std::begin(c2);
          auto e = std::end(c2);
          for ( ; b != e; ++b )
          {
             std::cout << *b << std::endl;
          }
       }
    
       {
          // Non-member functions with const-objects as argument are found
          auto b = begin(c2);
          auto e = end(c2);
          for ( ; b != e; ++b )
          {
             std::cout << *b << std::endl;
          }
       }
    }
    

提交回复
热议问题