Home > Net >  Why do C std container iterators ignore some template parameters of their underlying container?
Why do C std container iterators ignore some template parameters of their underlying container?

Time:09-20

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;
}

CodePudding user response:

Standard sets few constraints on iterator types and just impose 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.

CodePudding user response:

One practical reason is that this might lead to smaller executables. Your two map types can share one iterator type, so all the iterator functions are also shared.

  • Related