This is argument-dependent lookup. If you use typeid
to examine the types of the iterators involved:
#include <iostream>
#include <typeinfo>
#include <vector>
#include <array>
int main() {
std::cout << typeid(std::vector<int>::iterator).name() << '
';
std::cout << typeid(std::array<int, 5>::iterator).name() << std::endl;
return 0;
}
at least on Ideone, you get the following output:
N9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE
Pi
With Revolver_Ocelot's help in the comments, we see that these types are __gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >
and int*
.
For the vector, after the usual name lookup fails, the compiler searches the __gnu_cxx
and std
namespaces for a sort
function, __gnu_cxx
because it's the namespace of __gnu_cxx::normal_iterator
and std
because it's the namespace of one of the template arguments, std::vector<int, std::allocator<int> >
. It finds std::sort
.
For the std::array
, the iterators are just int*
s, so argument-dependent lookup searches no additional namespaces and finds no sort
function.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…