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
. SoT*
might be a valid iterator forstd::vector<T>
.they don't have to have same template parameters than their container. For above example
T*
might be an iterator forstd::vector<T, Allocator>
for anyAllocator
.
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.