首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >c++中的距离计算错误

c++中的距离计算错误
EN

Stack Overflow用户
提问于 2010-11-19 01:28:29
回答 2查看 5.2K关注 0票数 0
代码语言:javascript
复制
#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;
}

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

代码语言:javascript
复制
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 ==========
EN

回答 2

Stack Overflow用户

发布于 2010-11-19 01:31:22

这在一定程度上是由于您使用using namespace std;造成的。

在标准库std::distance中有一个函数,用于计算两个迭代器到容器中的距离。在重载解析过程中选择该函数,而不是选择distance函数。

如果你不使用using namespace std;,你就不会有这个问题。使用using namespace std;会将std名称空间中的所有名称放入全局名称空间中。这很糟糕,因为名称空间std中有许多常见的名称,并且在名称查找过程中可能会导致复杂的问题,正如您在这里所发现的那样。

通常,最好不要使用using namespace,尤其是在文件范围内。从长远来看,对您想要使用的每个名称进行限定要容易得多,也更清晰。

票数 26
EN

Stack Overflow用户

发布于 2010-11-19 03:29:44

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

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

这是基本的问题,简化了。

您可以调用返回vector::referencevector::const_referencevector::operator[]。您接受此返回值,并调用distance() unqualified。

因为在和可应用的类中找不到distance,所以ADL会起作用,它会得到太多可能匹配的名称。

然后,ADL遍历候选列表并选择“最佳匹配”。在这种情况下,operator[]返回的reference更接近std::distance期望的类型,而不是distance期望的类型,尽管两者都兼容,因此选择了std::distance

解决此问题的几种方法:

  1. ‘t using namespace std.取而代之的是,使用作用域解析操作符::distance()
  2. Change using want.
  3. Quantify来获取指针,而不是const &。这实际上关闭了ADL。用法:

示例:

代码语言:javascript
复制
int distance(const Point* a,const Point* b)
s+=square(distance(&a[0],&a[1]));

其他资源:

"A Modest Proposal: Fixing ADL (revision 2)" by Herb Sutter

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4217733

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档