暴露自定义STL样式迭代的首选方法是什么? [英] what is the preferred way to expose custom STL-style iteration?

查看:136
本文介绍了暴露自定义STL样式迭代的首选方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(另见是否有一种很好的方法可以在C ++中手动编写自定义类型的所有12个所需容器函数?

对于类等

namespace JDanielSmith {
class C
{
    const size_t _size;
    const std::unique_ptr<int[]> _data;

public:
    C(size_t size) : _size(size), _data(new int[size]) {}

    inline const int* get() const noexcept { return _data.get(); }
    inline int* get() noexcept { return _data.get(); }

    size_t size() const noexcept { return _size; }
};
}

公开迭代的首选方式是什么?我应该写 begin() / end()(和 cbegin() / cend())成员函数?

what is the preferred way to expose iteration? Should I write begin()/end() (and cbegin()/cend()) member functions?

const int* cbegin() const {
    return get();
}
const int* cend() const {
    return cbegin() + size();
}

或者这些是非会员功能吗?

or should these be non-member functions?

const int* cbegin(const C& c) {
    return c.get();
}
const int* cend(const C& c) {
    return cbegin(c) + c.size();
}

应该 begin() / end()同时具有 const 和非 const 重载?

Should begin()/end() have both const and non-const overloads?

    const int* begin() const {
        return get();
    }
    int* begin() {
        return get();
    }

还有其他需要考虑的事项吗?是否有工具/技术使这个容易变得正确并减少锅炉板代码的数量?

Are there any other things to consider? Are there tools/techniques to make this "easy to get right" and reduce the amount of boiler-plate code?

一些相关的问题/讨论包括:

Some related questions/discussion include:

  • Should custom containers have free begin/end functions?
  • Why use non-member begin and end functions in C++11?
  • When to use std::begin and std::end instead of container specific versions

推荐答案

我建议创建两组函数 - 成员函数和非成员函数 - 以允许最大化灵活性。

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<int[]> _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(); }
}

如果你想要能够使用的对象,必须使用成员函数输入 C 作为 std :: begin std :: end std :: cbegin std :: cend

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.

如果您希望能够使用 C 类型的对象作为 begin <的参数,则必须使用非成员函数/ code>,结束 cbegin cend 。 ADL将确保为这些用法找到非成员函数。

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

这篇关于暴露自定义STL样式迭代的首选方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆