C++ Iterator Quiz

C++
0 Passed
0% acceptance

40 in-depth questions covering C++ iterator fundamentals including iterator categories, STL container usage, begin/end patterns, reverse iterators, and iterator invalidation rules — with 16 code examples to master iterator-based programming.

40 Questions
~80 minutes
1

Question 1

What is an iterator in C++?

A
An object that enables traversal and access to elements in a container, providing a uniform interface for different container types through pointer-like operations
B
A pointer to the beginning of a container
C
A function that returns container elements
D
A type of smart pointer
2

Question 2

What are the five fundamental iterator categories in C++?

A
Input, output, forward, bidirectional, and random access iterators, each providing increasing capabilities for traversal and element access
B
Read-only, write-only, read-write, const, and mutable iterators
C
Forward, backward, circular, bounded, and unbounded iterators
D
Container, algorithm, stream, file, and memory iterators
3

Question 3

What is the difference between input and output iterators?

cpp
#include <iostream>
#include <iterator>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    
    // Output iterator (back_inserter)
    std::copy(vec.begin(), vec.end(), 
              std::back_inserter(vec));  // Can only write
    
    // Input iterator (istream_iterator)
    // std::copy(std::istream_iterator<int>(std::cin),
    //           std::istream_iterator<int>(),
    //           std::back_inserter(vec));  // Can only read
    
    return 0;
}
A
Input iterators support single-pass read-only traversal, output iterators support single-pass write-only traversal, both are the most basic iterator categories
B
Input iterators can write, output iterators can read
C
They are identical in functionality
D
Input iterators are faster than output iterators
4

Question 4

What capabilities does a forward iterator provide?

A
Multi-pass traversal in one direction with read and write access, combining input and output iterator capabilities while allowing multiple passes over the same range
B
Traversal in both directions with random access
C
Only single-pass read access
D
Only write access without reading
5

Question 5

What additional capabilities does a bidirectional iterator provide over forward iterators?

cpp
#include <list>
#include <algorithm>

int main() {
    std::list<int> lst = {1, 2, 3, 4, 5};
    
    // Bidirectional iterator can go backward
    auto it = std::find(lst.begin(), lst.end(), 3);
    if (it != lst.end()) {
        --it;  // Move backward - only possible with bidirectional
        std::cout << *it << std::endl;  // Prints 2
    }
    
    return 0;
}
A
Decrement operation (--it) to move backward through the sequence, enabling algorithms that need reverse traversal like reverse or sort
B
Random access with indexing and arithmetic
C
Multi-pass capability with independent iterators
D
Write-only access to elements
6

Question 6

What capabilities does a random access iterator provide?

cpp
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    
    // Random access iterator arithmetic
    auto it = vec.begin();
    std::advance(it, 3);  // Move forward by 3
    std::cout << *it << std::endl;  // 4
    
    auto it2 = it + 1;  // Iterator arithmetic
    std::cout << *it2 << std::endl;  // 5
    
    if (it2 > it) {  // Iterator comparison
        std::cout << "it2 is after it" << std::endl;
    }
    
    return 0;
}
A
Constant-time advancement by arbitrary amounts, iterator arithmetic (+, -, +=, -=), and comparison operators (<, >, <=, >=) enabling efficient algorithms like sort and binary search
B
Only forward movement with single steps
C
Multi-pass capability with independent copies
D
Write-only access with no reading capability
7

Question 7

What iterator category does std::vector provide?

A
Random access iterators, providing constant-time access to any element and full arithmetic and comparison capabilities
B
Bidirectional iterators only
C
Forward iterators only
D
Input iterators only
8

Question 8

What iterator category does std::list provide?

A
Bidirectional iterators, supporting forward and backward traversal but not random access due to the linked structure
B
Random access iterators
C
Forward iterators only
D
Input iterators only
9

Question 9

What iterator category do std::set and std::map provide?

A
Bidirectional iterators, allowing ordered traversal in both directions but no random access due to tree structure
B
Random access iterators
C
Forward iterators only
D
Input iterators only
10

Question 10

What is the purpose of begin() and end() member functions?

cpp
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    
    // begin() returns iterator to first element
    auto first = vec.begin();
    std::cout << *first << std::endl;  // 1
    
    // end() returns iterator to one-past-last element
    auto last = vec.end();
    --last;  // Move to actual last element
    std::cout << *last << std::endl;   // 5
    
    // Range-based algorithms
    std::sort(vec.begin(), vec.end());
    
    return 0;
}
A
begin() returns iterator to first element, end() returns iterator to one-past-last element, defining the valid range for algorithms and loops
B
begin() returns the first element value, end() returns the last element value
C
They return pointers to the container's memory
D
begin() and end() are identical functions
11

Question 11

What is a reverse iterator and how does it work?

cpp
#include <vector>
#include <iostream>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    
    // Reverse iterator from rbegin()
    auto rit = vec.rbegin();
    std::cout << *rit << std::endl;  // 5 (last element)
    
    ++rit;
    std::cout << *rit << std::endl;  // 4 (moving backward)
    
    // Convert to forward iterator
    auto fit = rit.base();  // Points to element after *rit
    std::cout << *fit << std::endl;   // 5
    
    return 0;
}
A
An iterator adapter that traverses the container in reverse order, where incrementing moves toward the beginning and dereferencing accesses elements as if traversing backward
B
An iterator that can only move backward, not forward
C
A special iterator for sorting in reverse order
D
An iterator that reverses the container's elements
12

Question 12

What is iterator invalidation and why is it dangerous?

cpp
#include <vector>
#include <iostream>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    auto it = vec.begin() + 2;  // Points to element 3
    
    std::cout << *it << std::endl;  // 3
    
    vec.push_back(6);  // May reallocate and invalidate iterators
    
    // it is now INVALID - undefined behavior!
    // std::cout << *it << std::endl;  // DANGER!
    
    return 0;
}
A
When container operations make existing iterators unsafe to dereference or increment, potentially causing undefined behavior, crashes, or data corruption if used after invalidation
B
When iterators go out of scope and are automatically destroyed
C
When iterator operations throw exceptions
D
Iterator invalidation only affects const iterators
13

Question 13

What operations can invalidate iterators in std::vector?

A
Operations that may cause reallocation (push_back, insert, resize) invalidate all iterators, while operations that don't reallocate (pop_back, erase from end) may invalidate some iterators
B
No operations invalidate vector iterators
C
Only clear() invalidates vector iterators
D
Iterator invalidation only occurs with const iterators
14

Question 14

What operations can invalidate iterators in std::list?

A
Only erase() and clear() invalidate the erased iterators, other operations (insert, splice) don't affect existing iterators since list uses node-based storage
B
All operations invalidate all iterators
C
No operations invalidate list iterators
D
Only push_back invalidates list iterators
15

Question 15

What operations can invalidate iterators in std::map and std::set?

A
Only erase() invalidates iterators to erased elements, insert() and other operations don't affect existing iterators due to tree structure stability
B
All operations invalidate all iterators
C
No operations invalidate map/set iterators
D
Only clear() invalidates map/set iterators
16

Question 16

What is the difference between const_iterator and iterator?

cpp
#include <vector>
#include <iostream>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    
    // Regular iterator - read/write access
    std::vector<int>::iterator it = vec.begin();
    *it = 10;  // Can modify
    std::cout << *it << std::endl;
    
    // Const iterator - read-only access
    std::vector<int>::const_iterator cit = vec.cbegin();
    // *cit = 20;  // Error: cannot modify through const_iterator
    std::cout << *cit << std::endl;
    
    // Auto with const container
    const std::vector<int> cvec = {1, 2, 3};
    auto cit2 = cvec.begin();  // const_iterator automatically
    
    return 0;
}
A
iterator allows modification of elements, const_iterator provides read-only access, enabling safe iteration over const containers
B
They are identical in functionality
C
const_iterator is faster than iterator
D
iterator can only be used with non-const containers
17

Question 17

What is a range-based for loop and how does it use iterators?

cpp
#include <vector>
#include <iostream>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    
    // Range-based for loop (uses iterators internally)
    for (int& value : vec) {
        value *= 2;
    }
    
    // Equivalent to:
    // for (auto it = vec.begin(); it != vec.end(); ++it) {
    //     int& value = *it;
    //     value *= 2;
    // }
    
    for (int value : vec) {
        std::cout << value << " ";
    }
    
    return 0;
}
A
Syntactic sugar that uses begin() and end() iterators internally to provide clean, safe traversal of containers without explicit iterator management
B
A special loop that only works with arrays, not containers
C
A loop that copies all elements instead of using iterators
D
A loop that requires manual iterator declaration and management
18

Question 18

What is std::advance and when should it be used?

cpp
#include <vector>
#include <list>
#include <algorithm>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    std::list<int> lst = {1, 2, 3, 4, 5};
    
    // For random access iterators (vector)
    auto vit = vec.begin();
    std::advance(vit, 3);  // Efficient O(1)
    std::cout << *vit << std::endl;  // 4
    
    // For bidirectional iterators (list)
    auto lit = lst.begin();
    std::advance(lit, 3);  // O(n) - less efficient
    std::cout << *lit << std::endl;  // 4
    
    return 0;
}
A
A generic function that advances any iterator by n positions, automatically choosing the most efficient method based on iterator category
B
A function that only works with random access iterators
C
A replacement for the ++ operator
D
A function that moves iterators backward only
19

Question 19

What is std::distance and how does it work with different iterator categories?

cpp
#include <vector>
#include <list>
#include <algorithm>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    std::list<int> lst = {1, 2, 3, 4, 5};
    
    // Random access (efficient)
    auto dist1 = std::distance(vec.begin(), vec.end());
    std::cout << dist1 << std::endl;  // 5, O(1)
    
    // Bidirectional (less efficient)
    auto dist2 = std::distance(lst.begin(), lst.end());
    std::cout << dist2 << std::endl;  // 5, O(n)
    
    return 0;
}
A
Calculates the number of elements between two iterators, using the most efficient method available for the iterator category (O(1) for random access, O(n) for others)
B
Only works with random access iterators
C
Returns the physical memory distance between iterators
D
Always takes O(n) time regardless of iterator category
20

Question 20

What is an iterator adaptor and what are some common examples?

A
Classes that modify iterator behavior, such as reverse_iterator (traverses backward), back_insert_iterator (inserts at end), and front_insert_iterator (inserts at beginning)
B
Functions that convert iterators to pointers
C
Classes that store multiple iterators
D
Iterator adaptors don't exist in C++
21

Question 21

What is the difference between std::back_inserter and std::front_inserter?

cpp
#include <vector>
#include <deque>
#include <algorithm>

int main() {
    std::vector<int> source = {1, 2, 3};
    std::vector<int> dest1;
    std::deque<int> dest2;
    
    // back_inserter adds to end
    std::copy(source.begin(), source.end(), 
              std::back_inserter(dest1));
    // dest1 now: {1, 2, 3}
    
    // front_inserter adds to beginning
    std::copy(source.begin(), source.end(), 
              std::front_inserter(dest2));
    // dest2 now: {3, 2, 1} (reverse order)
    
    return 0;
}
A
back_inserter calls push_back() to add elements at the end, front_inserter calls push_front() to add elements at the beginning, reversing the order
B
They are identical in functionality
C
back_inserter only works with vectors, front_inserter with deques
D
front_inserter is faster than back_inserter
22

Question 22

What is the difference between pre-increment and post-increment for iterators?

cpp
#include <vector>
#include <iostream>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    auto it = vec.begin();
    
    // Pre-increment: increment then use
    auto val1 = *++it;  // it now points to 2, val1 = 2
    std::cout << val1 << std::endl;
    
    // Reset iterator
    it = vec.begin();
    
    // Post-increment: use then increment
    auto val2 = *it++;  // val2 = 1, it now points to 2
    std::cout << val2 << std::endl;
    
    return 0;
}
A
Pre-increment (++it) increments first then returns reference to new position, post-increment (it++) returns copy of old position then increments, making pre-increment more efficient for iterators
B
They are identical for all iterator types
C
Post-increment is always more efficient
D
Pre-increment only works with random access iterators
23

Question 23

What is an iterator trait and why is it useful?

cpp
#include <iterator>
#include <vector>
#include <iostream>

template<typename Iter>
void advance_iterator(Iter& it, typename std::iterator_traits<Iter>::difference_type n) {
    // Use traits to get the difference type
    using diff_t = typename std::iterator_traits<Iter>::difference_type;
    
    if constexpr (std::is_same_v<typename std::iterator_traits<Iter>::iterator_category, 
                               std::random_access_iterator_tag>) {
        it += n;  // Efficient for random access
    } else {
        // Manual advancement for other categories
        for (diff_t i = 0; i < n; ++i) ++it;
    }
}

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    auto it = vec.begin();
    advance_iterator(it, 3);
    std::cout << *it << std::endl;  // 4
    
    return 0;
}
A
Type information associated with iterators (value_type, difference_type, iterator_category) that enables generic programming and optimization based on iterator capabilities
B
Runtime properties of iterator objects
C
Iterator traits are not used in modern C++
D
Traits that define iterator appearance and behavior
24

Question 24

What is the difference between iterator and const_iterator typedefs?

A
iterator allows element modification, const_iterator provides read-only access, with cbegin()/cend() providing const_iterator access to non-const containers
B
They are identical in functionality
C
const_iterator is faster than iterator
D
iterator can only be used with mutable containers
25

Question 25

What is the difference between std::cbegin() and std::begin()?

A
std::cbegin() returns a const_iterator for read-only access, std::begin() returns a regular iterator that may allow modification
B
They are identical in functionality
C
std::cbegin() is faster than std::begin()
D
std::begin() can only be used with non-const containers
26

Question 26

What is the difference between std::next() and std::advance()?

cpp
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    auto it = vec.begin();
    
    // advance modifies the iterator in-place
    std::advance(it, 2);
    std::cout << *it << std::endl;  // 3
    
    // next returns a new iterator, original unchanged
    auto it2 = std::next(it, 2);
    std::cout << *it << std::endl;   // Still 3
    std::cout << *it2 << std::endl;  // 5
    
    return 0;
}
A
advance() modifies the iterator in-place, next() returns a new advanced iterator without modifying the original, enabling functional programming patterns
B
They are identical in functionality
C
next() is faster than advance()
D
advance() can only move backward
27

Question 27

What is the difference between std::prev() and manual decrement?

A
std::prev() returns a new iterator to the previous position without modifying the original, while --it modifies the iterator in-place
B
They are identical in functionality
C
std::prev() is faster than manual decrement
D
Manual decrement can only be used with bidirectional iterators
28

Question 28

What is the difference between iterator tags and how are they used?

A
Empty classes (input_iterator_tag, etc.) used for tag dispatch to select optimal algorithm implementations based on iterator capabilities at compile-time
B
Runtime properties that define iterator speed
C
Iterator tags are not used in modern C++
D
Tags that define iterator visual appearance
29

Question 29

What is the difference between std::make_reverse_iterator() and rbegin()?

cpp
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    
    // Container's rbegin()
    auto rit1 = vec.rbegin();
    std::cout << *rit1 << std::endl;  // 5
    
    // make_reverse_iterator from forward iterator
    auto rit2 = std::make_reverse_iterator(vec.end());
    std::cout << *rit2 << std::endl;  // 5 (same result)
    
    return 0;
}
A
rbegin() is a container member function, make_reverse_iterator() is a free function that can create reverse iterators from any forward iterator
B
They are identical in functionality
C
make_reverse_iterator() is faster than rbegin()
D
rbegin() can only be used with vectors
30

Question 30

What is the difference between iterator invalidation in debug vs release builds?

A
Iterator invalidation causes undefined behavior in both debug and release, but debug builds may detect some invalidation through additional checks while release builds have no safety nets
B
Iterator invalidation only occurs in debug builds
C
Release builds prevent iterator invalidation automatically
D
Iterator invalidation has no impact on program behavior
31

Question 31

What is the difference between std::inserter and std::back_inserter?

cpp
#include <vector>
#include <set>
#include <algorithm>

int main() {
    std::vector<int> source = {1, 2, 3};
    std::set<int> dest;
    
    // inserter calls insert() at specified position
    std::copy(source.begin(), source.end(), 
              std::inserter(dest, dest.end()));
    // dest now: {1, 2, 3}
    
    // back_inserter calls push_back()
    std::vector<int> dest2;
    std::copy(source.begin(), source.end(), 
              std::back_inserter(dest2));
    // dest2 now: {1, 2, 3}
    
    return 0;
}
A
inserter calls insert() method allowing position specification, back_inserter calls push_back() for end insertion, with inserter working with associative containers
B
They are identical in functionality
C
back_inserter is faster than inserter
D
inserter can only be used with vectors
32

Question 32

What is the difference between iterator movement and element access?

A
Movement (++it) changes which element the iterator points to, access (*it) reads or writes the element at the current position without changing the iterator
B
They are identical operations
C
Movement only works with random access iterators
D
Access changes the iterator position
33

Question 33

What is the difference between std::end() and std::cend()?

A
std::cend() returns a const_iterator to one-past-last, std::end() returns a regular iterator that may allow modification of the past-the-end position
B
They are identical in functionality
C
std::end() is faster than std::cend()
D
std::cend() can only be used with empty containers
34

Question 34

What is the difference between iterator ranges and iterator pairs?

A
Iterator ranges define [begin, end) half-open intervals for algorithms, iterator pairs are two iterators that may not represent a valid range
B
They are identical concepts
C
Iterator pairs are faster than ranges
D
Ranges can only be used with random access iterators
35

Question 35

What is the difference between iterator stability and iterator validity?

A
Validity means the iterator can be safely dereferenced, stability means the iterator continues to point to the same element even after container modifications
B
They are identical concepts
C
Stability only applies to random access iterators
D
Validity is only checked in debug builds
36

Question 36

What is the difference between std::move_iterator and regular iterators?

cpp
#include <vector>
#include <algorithm>

int main() {
    std::vector<std::string> source = {"hello", "world", "test"};
    std::vector<std::string> dest;
    
    // Regular copy
    std::copy(source.begin(), source.end(), 
              std::back_inserter(dest));
    // dest has copies of strings
    
    // Move iterator for efficient transfer
    std::vector<std::string> dest2;
    std::copy(std::make_move_iterator(source.begin()), 
              std::make_move_iterator(source.end()), 
              std::back_inserter(dest2));
    // dest2 has moved-from strings, source may be in valid but unspecified state
    
    return 0;
}
A
std::move_iterator converts dereference operations to move operations, enabling efficient element transfer instead of copying during algorithms
B
They are identical in functionality
C
std::move_iterator is faster for all operations
D
Regular iterators can only copy elements
37

Question 37

What is the difference between iterator debugging and iterator checking?

A
Debugging provides runtime checks for invalid iterator operations in debug builds, checking validates iterator state before operations
B
They are identical features
C
Iterator debugging only works with vectors
D
Iterator checking is only available in release builds
38

Question 38

What is the difference between iterator position and iterator offset?

A
Position is the logical location in the sequence, offset is the distance from a reference point, with random access iterators supporting direct offset calculations
B
They are identical concepts
C
Offset only works with bidirectional iterators
D
Position is only used with forward iterators
39

Question 39

What is the difference between iterator lifetime and iterator scope?

A
Lifetime is how long the iterator object exists, scope determines where the iterator can be used safely relative to container modifications
B
They are identical concepts
C
Lifetime only applies to const iterators
D
Scope is only checked in debug builds
40

Question 40

What is the fundamental principle for safe iterator usage across different STL containers?

A
Understand each container's iterator invalidation rules and iterator category limitations, re-acquire iterators after invalidating operations, and prefer range-based operations when possible
B
All iterators behave identically regardless of container type
C
Iterator invalidation only occurs with vectors
D
Safe iterator usage requires avoiding all container modifications

QUIZZES IN C++