distance calculation error in c++ [closed]
Asked Answered
N

2

-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 ==========
Nonmetallic answered 18/11, 2010 at 17:28 Comment(2)
271 questions to date and still not able (or unwilling) to format code for readability ?Biting
Ran the code through VS' auto-formatter.Fuzz
M
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.

Myronmyrrh answered 18/11, 2010 at 17:31 Comment(8)
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!)Coeliac
+1, This is a great example post that shows the inherent problems with "using namespace xyz;" to save typing.Cathead
@winwaed: Another option would be using std::vector;Ciprian
Why would overload resolution choose the std::distance template instead of the distance provided here?Agamemnon
Well, now I know why James was asking me about my old rant against using namespace std;. Here it is. Note how tsubasa also had trouble with std::distance(). Coincidence?Fuzz
@Moo-Juice, it's not just for saving typing. I don't know about you, but I can understand map<list<string>, set<list<string> > > easily, but std::map<std::list<std::string>, std::set<std::list<std::string> > > just makes my eyes bleed.Nutrilite
@Shahbaz: That is what typedefs are for. That said, if you have a std::map<std::list<std::string>, std::set<std::list<std::string> > >, chances are you want to reconsider what you're doing.Myronmyrrh
@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.Nutrilite
S
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

Stifling answered 18/11, 2010 at 19:29 Comment(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?Incrocci

© 2022 - 2024 — McMap. All rights reserved.