正在弃用的std :: iterator的准备工作

Jon*_*Mee 58 c++ standards iterator deprecated c++17

3月21 ,标准委员会投票赞成批准P0174std::iterator提议的弃用:

对于读者而言,很长的void参数序列不仅仅是简单地typedef在类定义本身中提供预期的s,这是当前工作草案采用的方法,遵循设置的模式

之前std::iterator,鼓励继承从迭代器样板实现中删除乏味.但弃用将需要以下其中一项:

  1. 迭代器样板现在需要包含所有必需的typedefs
  2. 使用迭代器的算法现在需要使用auto而不是依赖于迭代器来声明类型
  3. 洛基阿斯塔曾建议std::iterator_traits,可以更新,而继承工作std::iterator

有人可以告诉我我应该期待哪些选项,因为我设计了自定义迭代器,着眼于兼容性?

Ami*_*rsh 36

讨论的替代方案很明确,但我觉得需要一个代码示例.

鉴于不会有语言替代而且不依赖于boost或您自己的迭代器基类版本,以下使用std::iterator的代码将固定到下面的代码中.

std::iterator

template<long FROM, long TO>
class Range {
public:
    // member typedefs provided through inheriting from std::iterator
    class iterator: public std::iterator<
                        std::forward_iterator_tag, // iterator_category
                        long,                      // value_type
                        long,                      // difference_type
                        const long*,               // pointer
                        const long&                // reference
                                      >{
        long num = FROM;
    public:
        iterator(long _num = 0) : num(_num) {}
        iterator& operator++() {num = TO >= FROM ? num + 1: num - 1; return *this;}
        iterator operator++(int) {iterator retval = *this; ++(*this); return retval;}
        bool operator==(iterator other) const {return num == other.num;}
        bool operator!=(iterator other) const {return !(*this == other);}
        long operator*() {return num;}
    };
    iterator begin() {return FROM;}
    iterator end() {return TO >= FROM? TO+1 : TO-1;}
};
Run Code Online (Sandbox Code Playgroud)

(来自http://en.cppreference.com/w/cpp/iterator/iterator并获得原作者许可的代码).

没有 std::iterator

template<long FROM, long TO>
class Range {
public:
    class iterator {
        long num = FROM;
    public:
        iterator(long _num = 0) : num(_num) {}
        iterator& operator++() {num = TO >= FROM ? num + 1: num - 1; return *this;}
        iterator operator++(int) {iterator retval = *this; ++(*this); return retval;}
        bool operator==(iterator other) const {return num == other.num;}
        bool operator!=(iterator other) const {return !(*this == other);}
        long operator*() {return num;}
        // iterator traits
        using difference_type = long;
        using value_type = long;
        using pointer = const long*;
        using reference = const long&;
        using iterator_category = std::forward_iterator_tag;
    };
    iterator begin() {return FROM;}
    iterator end() {return TO >= FROM? TO+1 : TO-1;}
};
Run Code Online (Sandbox Code Playgroud)

  • 我在[这里](https://www. Fluentcpp.com/2018/05/08/std-iterator-deprecated/)也发现了一篇关于它的非常精彩的文章,它概述了理由。 (5认同)
  • @AmirKirsh `operator*` 应该返回 `reference`,你需要一个 `operator-&gt;` 返回一个 `pointer`,即使它对 `long` 没有意义 (3认同)

Bar*_*rry 31

选项3是选项1的严格打字版本,因为您必须编写所有相同typedefs但另外包装iterator_traits<X>.

选项2作为解决方案是不可行的.你可以推断一些类型(例如reference只是decltype(*it)),但你不能推断iterator_category.由于无法反复检查迭代器是否满足多通道保证input_iterator_tag,因此无法区分forward_iterator_tag操作并且仅仅存在操作.此外,您无法真正区分这些以及output_iterator_tag迭代器是否产生可变引用.必须在某处明确提供它们.

这留下了选项1.猜猜我们应该习惯于编写所有样板文件.我是一个人,欢迎我们新的腕管道领主.

  • "我,一个人,欢迎我们新的腕管隧道霸主." 我读过的最伟大的一行 (16认同)
  • @TemplateRex这是一个笑话.无论如何,贬低`std :: iterator`以支持...现在每个人都编写自己的`std :: iterator`副本来解决这个问题似乎很愚蠢. (7认同)
  • @JonathanMee Dude."Iterator"和"Input Iterator"**不等同**. (6认同)
  • @JonathanMee这没有任何意义. (4认同)
  • 如果你真的喜欢`std :: iterator`的功能,你可以轻松编写自己的版本.所以腕管的风险高度夸大了. (3认同)
  • 相关:http://stackoverflow.com/q/29108958/819272标准中更常见的趋势是删除仅包含typedef的傻基类(unary_function等) (3认同)