Solution: Tag Dispatching

Get a detailed explanation of the solution to the tag dispatching exercise.

We'll cover the following...

Solution

Press + to interact
#include <iterator>
#include <forward_list>
#include <list>
#include <vector>
#include <iostream>
template <typename InputIterator, typename Distance>
void advance_impl(InputIterator& i, Distance n, std::input_iterator_tag) {
std::cout << "InputIterator used" << '\n';
while (n--) ++i;
}
template <typename BidirectionalIterator, typename Distance>
void advance_impl(BidirectionalIterator& i, Distance n, std::bidirectional_iterator_tag) {
std::cout << "BidirectionalIterator used" << '\n';
if (n >= 0)
while (n--) ++i;
else
while (n++) --i;
}
template <typename RandomAccessIterator, typename Distance>
void advance_impl(RandomAccessIterator& i, Distance n, std::random_access_iterator_tag) {
std::cout << "RandomAccessIterator used" << '\n';
i += n;
}
template <typename InputIterator, typename Distance>
void advance_(InputIterator& i, Distance n) {
typename std::iterator_traits<InputIterator>::iterator_category category;
advance_impl(i, n, category);
}
int main() {
// Vector (RandomAccessIterator)
std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::cout << "Vector iterator:" << std::endl;
auto vecIt = vec.begin();
std::cout << "Initial value: " << *vecIt << std::endl;
advance_(vecIt, 3);
std::cout << "Advanced to: " << *vecIt << std::endl;
// List (BidirectionalIterator)
std::list<int> lst = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::cout << "\nList iterator:" << std::endl;
auto lstIt = lst.begin();
std::cout << "Initial value: " << *lstIt << std::endl;
advance_(lstIt, 5);
std::cout << "Advanced to: " << *lstIt << std::endl;
advance_(lstIt, -2);
std::cout << "Advanced back to: " << *lstIt << std::endl;
// Forward List (ForwardIterator, which is a type of InputIterator)
std::forward_list<int> flst = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::cout << "\nForward list iterator:" << std::endl;
auto flstIt = flst.begin();
std::cout << "Initial value: " << *flstIt << std::endl;
advance_(flstIt, 7);
std::cout << "Advanced to: " << *flstIt << std::endl;
return 0;
}

Explanation

Here is the code where we have different implementations of advance_ based on iterator_category.

  • Line 36: We define a vector vec and initialize it with elements from ...