-1
#include <iostream>
#include <cmath>
#include <vector>

using namespace std;

int square(int a){
    return a*a;
}
struct  Point{
    int x,y;

};
int distance (const  Point& a,const Point& b){
    int k=(int) sqrt((float)((a.x-b.x)*(a.x-b.x))+((a.y-b.y)*(a.y-b.y)));
    return k;

}
int main(){

    vector<Point>a(10);
    for (int i=0;i<10;i++){
        cin>>a[i].x>>a[i].y;
    }

    int s=0;
    int s1;
    int k=0; 
    for (int i=1;i<10;i++){

        s+=square(distance(a[0],a[i]));
    }
    for (int i=1;i<10;i++){
        s1=0;
        for (int j=0;j<10;j++){
            s1+=square(distance(a[i],a[j]));

            if (s1<s) {  s=s1; k=i;}

        }
    }
    cout<<k<<"Points are:";
    cout<<a[k].x;
    cout<<a[k].y;


    return 0;
}

i have following code but here is list of errors

1>------ Build started: Project: distance, Configuration: Debug Win32 ------
1>  distance.cpp
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(373): error C2039: 'iterator_category' : is not a member of 'Point'
1>          d:\c++_algorithms\distance\distance\distance.cpp(9) : see declaration of 'Point'
1>          d:\c++_algorithms\distance\distance\distance.cpp(30) : see reference to class template instantiation 'std::iterator_traits<_Iter>' being compiled
1>          with
1>          [
1>              _Iter=Point
1>          ]
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(373): error C2146: syntax error : missing ';' before identifier 'iterator_category'
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(373): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(373): error C2602: 'std::iterator_traits<_Iter>::iterator_category' is not a member of a base class of 'std::iterator_traits<_Iter>'
1>          with
1>          [
1>              _Iter=Point
1>          ]
1>          c:\program files\microsoft visual studio 10.0\vc\include\xutility(373) : see declaration of 'std::iterator_traits<_Iter>::iterator_category'
1>          with
1>          [
1>              _Iter=Point
1>          ]
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(373): error C2868: 'std::iterator_traits<_Iter>::iterator_category' : illegal syntax for using-declaration; expected qualified-name
1>          with
1>          [
1>              _Iter=Point
1>          ]
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(374): error C2039: 'value_type' : is not a member of 'Point'
1>          d:\c++_algorithms\distance\distance\distance.cpp(9) : see declaration of 'Point'
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(374): error C2146: syntax error : missing ';' before identifier 'value_type'
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(374): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(374): error C2602: 'std::iterator_traits<_Iter>::value_type' is not a member of a base class of 'std::iterator_traits<_Iter>'
1>          with
1>          [
1>              _Iter=Point
1>          ]
1>          c:\program files\microsoft visual studio 10.0\vc\include\xutility(374) : see declaration of 'std::iterator_traits<_Iter>::value_type'
1>          with
1>          [
1>              _Iter=Point
1>          ]
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(374): error C2868: 'std::iterator_traits<_Iter>::value_type' : illegal syntax for using-declaration; expected qualified-name
1>          with
1>          [
1>              _Iter=Point
1>          ]
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(375): error C2039: 'difference_type' : is not a member of 'Point'
1>          d:\c++_algorithms\distance\distance\distance.cpp(9) : see declaration of 'Point'
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(375): error C2146: syntax error : missing ';' before identifier 'difference_type'
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(375): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(375): error C2602: 'std::iterator_traits<_Iter>::difference_type' is not a member of a base class of 'std::iterator_traits<_Iter>'
1>          with
1>          [
1>              _Iter=Point
1>          ]
1>          c:\program files\microsoft visual studio 10.0\vc\include\xutility(375) : see declaration of 'std::iterator_traits<_Iter>::difference_type'
1>          with
1>          [
1>              _Iter=Point
1>          ]
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(375): error C2868: 'std::iterator_traits<_Iter>::difference_type' : illegal syntax for using-declaration; expected qualified-name
1>          with
1>          [
1>              _Iter=Point
1>          ]
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(377): error C2039: 'pointer' : is not a member of 'Point'
1>          d:\c++_algorithms\distance\distance\distance.cpp(9) : see declaration of 'Point'
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(377): error C2146: syntax error : missing ';' before identifier 'pointer'
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(377): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(377): error C2602: 'std::iterator_traits<_Iter>::pointer' is not a member of a base class of 'std::iterator_traits<_Iter>'
1>          with
1>          [
1>              _Iter=Point
1>          ]
1>          c:\program files\microsoft visual studio 10.0\vc\include\xutility(377) : see declaration of 'std::iterator_traits<_Iter>::pointer'
1>          with
1>          [
1>              _Iter=Point
1>          ]
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(377): error C2868: 'std::iterator_traits<_Iter>::pointer' : illegal syntax for using-declaration; expected qualified-name
1>          with
1>          [
1>              _Iter=Point
1>          ]
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(378): error C2039: 'reference' : is not a member of 'Point'
1>          d:\c++_algorithms\distance\distance\distance.cpp(9) : see declaration of 'Point'
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(378): error C2146: syntax error : missing ';' before identifier 'reference'
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(378): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(378): error C2602: 'std::iterator_traits<_Iter>::reference' is not a member of a base class of 'std::iterator_traits<_Iter>'
1>          with
1>          [
1>              _Iter=Point
1>          ]
1>          c:\program files\microsoft visual studio 10.0\vc\include\xutility(378) : see declaration of 'std::iterator_traits<_Iter>::reference'
1>          with
1>          [
1>              _Iter=Point
1>          ]
1>c:\program files\microsoft visual studio 10.0\vc\include\xutility(378): error C2868: 'std::iterator_traits<_Iter>::reference' : illegal syntax for using-declaration; expected qualified-name
1>          with
1>          [
1>              _Iter=Point
1>          ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
sbi
  • 219,715
  • 46
  • 258
  • 445

2 Answers2

26

This is caused in part by your use of using namespace std;.

There is a function in the standard library, std::distance, that is used to compute the distance between two iterators into a container. That function is being selected during overload resolution instead of your distance function.

If you don't use using namespace std;, you won't have this problem. Your use of using namespace std; brings all of the names from the std namespace into the global namespace. This is bad because there are a lot of common names in namespace std and it can cause convoluted issues during name lookup, as you've discovered here.

In general, prefer not to use using namespace, especially not at file scope. It's far easier and clearer in the long run to qualify each of the names that you want to use.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • The Op will then need to use std::vector for the vector definition. (adding for completeness to try and pre-empt the next compiler error!) – winwaed Nov 18 '10 at 17:33
  • 10
    +1, This is a great example post that shows the inherent problems with "using namespace xyz;" to save typing. – Moo-Juice Nov 18 '10 at 17:35
  • 3
    @winwaed: Another option would be `using std::vector;` – Fred Larson Nov 18 '10 at 17:46
  • 1
    Why would overload resolution choose the `std::distance` template instead of the `distance` provided here? – Rob Kennedy Nov 18 '10 at 18:30
  • 2
    Well, now I know why James was asking me about my old rant against `using namespace std;`. [Here it is.](http://stackoverflow.com/questions/2879555/2880136#2880136) Note how [tsubasa also had trouble with `std::distance()`](http://stackoverflow.com/questions/2712076/2712125#2712125). Coincidence? – sbi Nov 18 '10 at 19:16
  • @Moo-Juice, it's not just for saving typing. I don't know about you, but I can understand `map, set > >` easily, but `std::map, std::set > >` just makes my eyes bleed. – Shahbaz Nov 02 '11 at 23:57
  • @Shahbaz: That is what `typedef`s are for. That said, if you have a `std::map, std::set > >`, chances are you want to reconsider what you're doing. – James McNellis Nov 02 '11 at 23:59
  • @JamesMcNellis, oh of course, but you still have to write that abomination down at least once. I don't argue that `using namespace std;` isn't bad. I had problem with it once myself, too. But I still prefer to keep my function names obviously distinct from anything that could be in `std` that `using namespace std;` wouldn't cause me problems. – Shahbaz Nov 03 '11 at 00:10
5

@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:

  1. Don't using namespace std. Instead, using just the peices you want.
  2. Quantify explicitly which distance you refer to using the scope resolution operator: ::distance()
  3. 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

John Dibling
  • 99,718
  • 31
  • 186
  • 324
  • 1
    Still don't get how a template can be a better match than a non-template. BTW, the vector is irrelevant and the error is the same if `a` is a plain array? – UncleBens Nov 18 '10 at 20:05