c++ - after - Llamando una función const en lugar de su versión no const.
const int (4)
No importa si Data::x
es una función constante o no. El operador al que se llama pertenece a la clase container<Data>
y no a la clase Data
, y su instancia no es constante, por lo que se llama al operador no constante. Si solo hubiera un operador constante disponible o la instancia de la clase fuera constante, el operador constante habría sido llamado.
Traté de envolver algo similar a los punteros de datos compartidos de Qt para mis propósitos, y al probar descubrí que cuando se debía llamar a la función const, se eligió su versión no const.
Estoy compilando con las opciones de C ++ 0x, y aquí hay un código mínimo:
struct Data {
int x() const {
return 1;
}
};
template <class T>
struct container
{
container() {
ptr = new T();
}
T & operator*() {
puts("non const data ptr");
return *ptr;
}
T * operator->() {
puts("non const data ptr");
return ptr;
}
const T & operator*() const {
puts("const data ptr");
return *ptr;
}
const T * operator->() const {
puts("const data ptr");
return ptr;
}
T* ptr;
};
typedef container<Data> testType;
void testing() {
testType test;
test->x();
}
Como puede ver, Data.x es una función de const, por lo que el operador -> llamado debería ser el de const. Y cuando comento el no constante, se compila sin errores, por lo que es posible. Sin embargo, mi terminal imprime:
"non const data ptr"
¿Es un error de GCC (tengo 4.5.2), o hay algo que me falta?
Pero testType
no es un objeto const.
Así llamará a la versión non const de sus miembros.
Si los métodos tienen exactamente los mismos parámetros, tiene que elegir la versión a la que llamar (por lo que usa este parámetro (el oculto)). En este caso, esto no es constante, por lo que se obtiene el método no constante.
testType const test2;
test2->x(); // This will call the const version
Esto no afecta la llamada a x (), ya que puede llamar a un método const en un objeto no const.
Si tiene dos sobrecargas que difieren solo en su constabilidad, entonces el compilador resuelve la llamada en función de si *this
es const
o no. En su código de ejemplo, la test
no es const
, por lo que se llama la sobrecarga no const
.
Si hiciste esto:
testType test;
const testType &test2 = test;
test2->x();
debería ver que se llama a la otra sobrecarga, porque test2
es const
.
test
es un objeto no constante, por lo que el compilador encuentra la mejor coincidencia: la versión no constante. Puede aplicar constness con static_cast
aunque: static_cast<const testType&>(test)->x();
EDITAR: Aparte de eso, como sospechaba que el 99.9% del tiempo pensaba que había encontrado un error en el compilador, debería volver a visitar su código, ya que es probable que exista alguna peculiaridad extraña y el compilador sigue el estándar.