Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do C++ std container iterators ignore some template parameters of their underlying container?

Here is a specific example. In the code below, I would have expected a compilation error like "cannot assign value of type std::map<int, int, cmp>::iterator to variable of type std::map<int, int>::iterator". However, I am able to compile the code without any issues (g++ C++20 Wall). Thanks for help.

#include <map>

struct cmp {
    bool operator()(const int a, const int b) const { return a > b; }
};

int main(int argc, char *argv[]) {

    std::map<int, int> m1;
    std::map<int, int>::iterator m1_it = m1.begin();

    std::map<int, int, cmp> m2;
    std::map<int, int, cmp>::iterator m2_it = m2.begin();

    // Why do these work?
    m1_it = m2.begin();
    m2_it = m1.begin();

    return 0;
}

like image 562
Alexander Richter Avatar asked Sep 04 '25 17:09

Alexander Richter


1 Answers

Standard sets few constraints on iterator types and just imposes some behaviours.

In particular:

  • they don't have to be in namespace std. So T* might be a valid iterator for std::vector<T>.

  • they don't have to have same template parameters than their container. For above example T* might be an iterator for std::vector<T, Allocator> for any Allocator.

Whereas, indeed, it is less type safe, less template parameter allows less instantiations (faster compilation, less generated similar code, ...).

Notice that your code might not compile for compilers/libraries which uses all template parameters for their iterators.

like image 102
Jarod42 Avatar answered Sep 06 '25 18:09

Jarod42