【问题标题】:Custom iterator for value checking用于值检查的自定义迭代器
【发布时间】:2021-02-08 02:37:33
【问题描述】:

我是迭代器的新手,并试图获得更多关于它们的知识。

这就是为什么我试图创建一个自定义迭代器来遍历给定的字符串数组以检查该字符串的任何值是否为十进制值。我想出了下面给出的实现:

集合是我的迭代器的用户

// Collection type
template <class T, int N>
class Collection
{
    // Holder for our collection
    // N is the size for our collection
    T data[N];

public:

    Collection(T _data[N]) { copy_n(_data, N, data); }

    // Method to return the iterator to the beginning of the collection
    CollectionIterator<T> begin()
    {
        return CollectionIterator<T>(data);
    }
    // Method to return the iterator to the end of the collection
    CollectionIterator<T> end()
    {
        return CollectionIterator<T>(data + N);
    }
};

CollectionIterator 是我的自定义迭代器(带有一种输入迭代器)

template <class T>
class CollectionIterator
{
    T *data;

public:
    using iterator_category = std::input_iterator_tag;
    using value_type = T;
    using difference_type = size_t;                         
    using pointer = T*;
    using reference = T&;

    // Default constructor
    CollectionIterator(){}
    CollectionIterator(pointer _data): data(_data) {}

    reference operator*()
    {
        if(is_number(*data))
        {
            std::cout << *data;
        }
        return *data;
    }

    bool operator!=(const CollectionIterator &other)
    {
        return data != other.data;
    }

    CollectionIterator<T>& operator++()
    {
        data += 1;
        return *this;
    }

    CollectionIterator<T> operator++(int)
    {
        return CollectionIterator<T>(data + 1);
    }

    bool is_number(const std::string& s)
    {
        return !s.empty() && std::find_if(s.begin(),
            s.end(), [](unsigned char c) { return !std::isdigit(c); }) == s.end();
    }
};

下面你可以看到我是如何使用集合类的。

std::string s[8] = { "2", "hello", "world", "asd5", "19870717", "sadsad7", "8", "byby" };

Collection <std::string, 8> test (s);

for (auto t = test.begin(); t != test.end(); t++){ }

当我运行代码时,我希望看到 2 19870717 8 但它不打印任何内容。我的代码中是否遗漏了什么或有什么问题?

【问题讨论】:

  • 您只在CollectionIterator::operator* 中打印,但您永远不会取消引用CollectionIterator 的实例,因此永远不会调用operator*
  • 有几个问题。一个是您没有正确实现后缀 ++ 运算符(它应该返回对象 before 增量的状态),但无论如何您都应该使用带有迭代器的前缀 ++ 运算符(这就是你的操作员 ++ 正在做)。
  • @IgorTandetnik 如果我在 for 循环中使用像 cout
  • 您的后增量运算符实际上并没有增加 data 成员,因此您有一个无限循环。换句话说,在auto t = test.begin(); t++; 之后,你仍然有t == test.begin()(或者更确切地说,!(t != test.begin()),因为你还没有实现operator==)。编写的示例,仅添加了*tprints 2 forever
  • @IgorTandetnik 啊,我明白了。我更改了前后增量,如下所示,它可以工作。这是正确的实施方式吗? CollectionIterator& operator++() { CollectionIterator i = *this;数据++;返回我; } CollectionIterator operator++(int) { data++;返回*这个; }

标签: c++ iterator std


【解决方案1】:

所以基本上,我的 post 和 pre increment 实现是不正确的。当我如下更改它们时,它可以工作。

bool operator==(const CollectionIterator &other)
{
    return data == other.data;
}

CollectionIterator<T>& operator++()
{
    data++;

    return *this;
}

CollectionIterator<T> operator++(int)
{
    CollectionIterator i = *this;

    data++;

    return i;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-18
    • 1970-01-01
    • 1970-01-01
    • 2013-02-17
    • 2015-02-04
    • 2014-08-07
    • 1970-01-01
    相关资源
    最近更新 更多