error de cálculo de distancia en c++
compiler-errors using-directives (2)
@James tiene razón en que deshacerse del using namespace std
de using namespace std
hará que este problema desaparezca. Pero ese no es exactamente el verdadero problema.
El problema proviene de la forma en que los nombres se resuelven en C ++. C ++ utiliza un enfoque muy agresivo para resolver las búsquedas de nombres cuando se resuelven los nombres de las funciones gratuitas si no se encontró un miembro de la clase adecuado. Esto se denomina búsqueda de nombre dependiente de argumento (o ADL), a veces denominado búsqueda de Koenig. Y al mismo tiempo, es una de las cosas que hace que C ++ sea tan poderoso, pero también tan mortal y confuso.
Aquí está el problema básico, simplificado.
vector::const_reference
vector::operator[]
que devuelve un vector::reference
o un vector::const_reference
. Tomas este valor de retorno y call distance()
sin calificar.
Debido a que no se encontró la distance
y la clase aplicable, se activa la ADL, que se apaga y recibe demasiados nombres coincidentes potenciales .
Luego, ADL revisa la lista de candidatos y selecciona "el mejor partido". En este caso, la reference
que devuelve el operator[]
coincide más con el tipo esperado por std::distance
que con su distance
, aunque ambos son compatibles, por lo que se selecciona std::distance
.
Varias formas de resolver este problema:
- No
using namespace std
En cambio,using
solo las cosas que quieras. - Cuantifique explícitamente la
distance
que se refiere utilizando el operador de resolución de alcance:::distance()
- Cambiar la
distance
para tomar punteros en lugar deconst &
. Esto efectivamente desactiva la ADL .:
Ejemplo:
int distance(const Point* a,const Point* b)
s+=square(distance(&a[0],&a[1]));
Recursos adicionales:
"Una propuesta modesta: reparación de ADL (revisión 2)" por Herb Sutter
#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;
}
Tengo el siguiente código pero aquí hay una lista de errores
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 ==========
Esto se debe en parte a su uso de using namespace std;
.
Hay una función en la biblioteca estándar, std::distance
, que se utiliza para calcular la distancia entre dos iteradores en un contenedor. Esa función se está seleccionando durante la resolución de sobrecarga en lugar de su función de distance
.
Si no using namespace std;
, no tendrás este problema Su uso de using namespace std;
trae todos los nombres del std
nombres std
espacio de nombres global. Esto es malo porque hay muchos nombres comunes en el espacio de nombres std
y puede causar problemas intrincados durante la búsqueda de nombres, como ha descubierto aquí.
En general, prefiere no usar el using namespace
, especialmente no en el alcance del archivo. Es mucho más fácil y claro a largo plazo calificar cada uno de los nombres que desea usar.