@James is right in that getting rid of using namespace std
will make this problem go away. But that's not exactly what the actual problem is.
The problem comes from the way names are resolved in C++. C++ uses a very aggressive approach to resolving name lookups when resolving the names of free functions if no suitable class member was found. This is called Argument-dependent name lookup (or ADL), sometimes referred to as Koenig lookup. And at the same time, it is one of the things makes C++ so powerful, but also so deadly and confounding.
Here's the basic problem, simplified.
You call vector::operator[]
which returns a vector::reference
or a vector::const_reference
. You take this return value and call distance()
unqualified.
Because distance
wasn't found in and applicable class, ADL kicks in, which goes out and gets too many potential matching names.
ADL then goes through the list of candidates and picks "the best match". In this case, the reference
that operator[]
returns is a closer match to the type expected by std::distance
than by your distance
, although both are compatible, so std::distance
is selected.
Several ways to solve this problem:
- Don't
using namespace std
. Instead, using
just the peices you want.
- Quantify explicitly which
distance
you refer to using the scope resolution operator: ::distance()
- Change
distance
to take pointers instead of const &
. This effectively turns off ADL.:
Example:
int distance(const Point* a,const Point* b)
s+=square(distance(&a[0],&a[1]));
Additional Resources:
"A Modest Proposal: Fixing ADL (revision 2)" by Herb Sutter