Creating Custom Iterators using C++20 Concepts

Using Iterator Category Tags in C++

What are iterator category tags and how do I use them in C++?

Abstract art representing computer programming

Iterator category tags in C++ are used to specify the capabilities of an iterator. They help algorithms determine what operations can be performed with the iterator. The main categories are:

  • std::input_iterator_tag
  • std::output_iterator_tag
  • std::forward_iterator_tag
  • std::bidirectional_iterator_tag
  • std::random_access_iterator_tag
  • std::contiguous_iterator_tag

For example, to create a forward iterator for a custom container, you can use std::forward_iterator_tag. Here's how to implement it:

#include <iostream>
#include <string>
#include <iterator>
#include <stdexcept>

class Player {
public:
  std::string Name;
};

class Party {
public:
  Party(Player A, Player B, Player C)
    : A{A}, B{B}, C{C} {}

  Player A, B, C;

  class Iterator {
  public:
    using iterator_category = std::forward_iterator_tag;
    using value_type = Player;
    using difference_type = std::ptrdiff_t;
    using pointer = Player*;
    using reference = Player&;

    Iterator(Party* ptr, size_t idx)
      : Party(ptr), idx(idx) {}

    Player& operator*() const {
      if (idx == 0) return Party->A;
      if (idx == 1) return Party->B;
      if (idx == 2) return Party->C;
      throw std::out_of_range("Invalid index");
    }

    Iterator& operator++() {
      ++idx;
      return *this;
    }

    bool operator==(const Iterator& other) const {
      return Party == other.Party && idx == other.idx;
    }

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

  private:
    size_t idx;
    Party* Party;
  };

  Iterator begin() { return Iterator(this, 0); }
  Iterator end() { return Iterator(this, 3); }
};

int main() {
  Party party{Player{"Anna"},
    Player{"Bob"}, Player{"Cara"}};

  for (Player& p : party) {
    std::cout << p.Name << ", ";
  }
}
Anna, Bob, Cara,

Explanation

  • iterator_category: Specifies that the Iterator is a forward iterator.
  • value_type, difference_type, pointer, reference: These typedefs provide information about the types used by the iterator.

Using these tags and typedefs makes your iterator more compatible with the standard library algorithms and allows the compiler to optimize code based on the iterator's capabilities.

Answers to questions are automatically generated and may not have been reviewed.

A computer programmer
Part of the course:

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Free, unlimited access

This course includes:

  • 124 Lessons
  • 550+ Code Samples
  • 96% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved