c ++中的距离计算错误

dat*_*ili 0 c++ compiler-errors using-directives overload-resolution name-lookup

#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;
}
Run Code Online (Sandbox Code Playgroud)

我有以下代码,但这里是错误列表

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 ==========
Run Code Online (Sandbox Code Playgroud)

Jam*_*lis 26

这部分是由于您的使用造成的using namespace std;.

标准库中有一个函数,std::distance用于计算两个迭代器之间到容器的距离.在重载决策期间选择该功能而不是您的distance功能.

如果您不使用using namespace std;,则不会出现此问题.您的使用using namespace std;std命名空间中的所有名称都带入全局命名空间.这很糟糕,因为在命名空间中有很多常用名称std,它可能会在名称查找过程中导致复杂的问题,正如您在此处发现的那样.

一般情况下,不要使用using namespace,尤其不要在文件范围内使用.从长远来看,要使用您想要使用的每个名称都要容易和清晰.

  • +1,这是一个很好的示例帖子,显示了"使用命名空间xyz"的固有问题.保存打字. (10认同)
  • @winwaed:另一种选择是`使用std :: vector;` (3认同)
  • 好吧,现在我知道为什么詹姆斯问我关于`使用命名空间std;`的旧咆哮.[这里是.](http://stackoverflow.com/questions/2879555/2880136#2880136)注意[tsubasa也遇到了'std :: distance()`的问题(http://stackoverflow.com/questions /2712125分之2712076#2712125).巧合? (2认同)

Joh*_*ing 5

@James 是对的,摆脱using namespace std会让这个问题消失。但这并不完全是实际问题所在。

问题来自于 C++ 中名称的解析方式。如果没有找到合适的类成员,则在解析自由函数的名称时,C++ 使用非常激进的方法来解析名称查找。这称为参数相关名称查找(或 ADL),有时称为 Koenig 查找。同时,它也是 C++ 如此强大,但也如此致命和令人困惑的原因之一。

这是基本问题,经过简化。

您调用vector::operator[]它返回 avector::reference或 a vector::const_reference。您获取此返回值并调用distance()unqualified。

因为distance在适用的类中找不到,所以 ADL 启动,它会出去并获取太多潜在的匹配名称

然后,ADL 会仔细检查候选者列表并选择“最佳匹配”。在这种情况下,返回reference的比您的operator[]期望的类型更匹配,尽管两者兼容,因此被选中。std::distancedistancestd::distance

解决这个问题的几种方法:

  1. using namespace std。相反,using只有您想要的部分。
  2. distance使用范围解析运算符明确量化您所引用的内容:::distance()
  3. 更改distance为采用指针而不是const &. 这有效地关闭了 ADL:

例子:

int distance(const Point* a,const Point* b)
s+=square(distance(&a[0],&a[1]));
Run Code Online (Sandbox Code Playgroud)

其他资源:

“一个温和的建议:修复 ADL(修订版 2)”作者:Herb Sutter