c++ - after - constint




Llamando una función const en lugar de su versión no const. (3)

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?


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.


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.


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.







const