c++ – Exceptions when working with iterators

Question:

I solve the following problem: there is a file, the structure of which is a set of blocks. Each block has a title and a body. The last block is marked with the corresponding identifier. To traverse blocks in a file, I write my own iterator:

/**
 * @brief Single-pass input iterator.
 */
class BlockIterator : public std::iterator<std::input_iterator_tag, const DataBlock> {
  private:
    friend class FileReader;

    FileReader* reader;

    // Текущий блок, на который указывает итератор.
    std::unique_ptr<DataBlock> block;

    BlockIterator(FileReader* r, std::unique_ptr<DataBlock> b) noexcept : reader(r), block(std::move(b)) {
        /*NOP*/
    };

  public:
    BlockIterator& operator++() {
        auto nextBlockOffset = block->offset + block->headerSize + block->bodySize;
        block = reader->getBlockAt(nextBlockOffset);
        //              ^^^ Функция может выкидывать исключение!
        return *this;
    }

    BlockIterator operator++(int) {
        auto retval = *this;
        ++(*this);
        return retval;
    }

    bool operator==(const BlockIterator& other) const {
        return reader == other.reader && block == other.block;
    }

    bool operator!=(const BlockIterator& other) const {
        return !(*this == other);
    }

    reference operator*() const {
        return *block;
    }
};

When incrementing, the getBlockAt() function may throw an exception (for example, if we are parsing an invalid file). What is the best way to proceed in this case: is it necessary to guarantee that there are no exceptions when working with an iterator? If so, how do you ensure that the iterator is invalidated and the error is displayed?

Answer:

Since there is inheritance from std :: iterator <…>, it makes sense to keep its ideology of handling such errors.

According to the latest published draft of the C ++ standard , an exception needs to be thrown:

Results of most expressions are undefined for singular values; the only exceptions are destroying an iterator that holds a singular value …

P. 856, p. 7

Scroll to Top