0
#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;
}

私は次のコードを持っていますが、ここにエラーのリストがあります

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 ==========
4

2 に答える 2

26

これは、 の使用が原因の 1 つですusing namespace std;

標準ライブラリにはstd::distance、コンテナへの 2 つのイテレータ間の距離を計算するために使用される関数があります。その関数は、関数の代わりにオーバーロードの解決中に選択されていdistanceます。

を使用しない場合using namespace std;、この問題は発生しません。を使用すると、名前空間using namespace std;のすべてのstd名前がグローバル名前空間に取り込まれます。ここで発見したように、名前空間には多くの一般的な名前があり、std名前の検索中に複雑な問題が発生する可能性があるため、これは悪いことです。

一般にusing namespace、特にファイル スコープでは使用しないことをお勧めします。長い目で見れば、使用する名前をそれぞれ修飾する方がはるかに簡単で明確です。

于 2010-11-18T17:31:21.827 に答える
5

@Jamesは、取り除くusing namespace stdことでこの問題が解消されるという点で正しいです。しかし、実際の問題はそれだけではありません。

この問題は、C++ での名前の解決方法に起因しています。C++ は、適切なクラス メンバーが見つからない場合にフリー関数の名前を解決するときに、非常に積極的な方法で名前ルックアップを解決します。これは、引数依存の名前ルックアップ(または ADL) と呼ばれ、Koenig ルックアップと呼ばれることもあります。同時に、これは C++ を非常に強力にするものの 1 つですが、非常に致命的で混乱を招くものでもあります。

これが基本的な問題で、単純化されています。

またはvector::operator[]を返す which を呼び出します。この戻り値を取得して、非修飾で呼び出します。 vector::referencevector::const_referencedistance()

該当するクラスで見つからなかったため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]));

追加リソース:

「ささやかな提案: ADL の修正 (改訂 2)」ハーブ・サッター著

于 2010-11-18T19:29:43.743 に答える