¿Por qué la deducción de tipo de devolución automática funciona con tipos no completamente definidos?


Considere lo siguiente:

template<typename Der>
struct Base {
    // NOTE: if I replace the decltype(...) below with auto, code compiles
    decltype(&Der::operator()) getCallOperator() const {
        return &Der::operator();
    }
};

struct Foo : Base<Foo> {
    double operator()(int, int) const {
        return 0.0;
    }
};

int main() {
    Foo f;
    auto callOp = f.getCallOperator();
}

Quiero crear una función miembro en la clase base CRTP con un tipo devuelto dependiendo de la firma de operator() en la clase derivada. Sin embargo decltype(&Der::operator()) falla al compilar; La función miembro operator() en Foo no es visible. Asumo que esto se debe a que la plantilla de la clase base se crea una instancia antes de que Foo esté completamente definida.

Sorprendentemente, si pongo auto para el tipo de retorno que compila. Supuse que auto haría que el compilador deduce el tipo devuelto desde el cuerpo de la función y fail-porque el cuerpo utiliza el tipo Foo no completamente definido.

Este comportamiento es el mismo para MSVC 2015.3 y Clang 3.8

¿Por qué el código comenzó a funcionar con auto? ¿auto la deducción de tipo de alguna manera "retrasa" la instanciación? ¿O usar un contexto diferente que una expresión de tipo de retorno escrita a mano?

Author: 4444, 2016-07-12

1 answers

Tu suposición es correcta. Un tipo de retorno deducido no se deduce realmente hasta que se necesita la firma de la función. Esto significa que se deducirá en el contexto de la llamada a getCallOperator, momento en el que Foo está completamente definido.

Esto se especifica en 7.1.6. 4p12:

La deducción de tipo de retorno para una plantilla de función con un marcador de posición en su tipo declarado se produce cuando se crea una instancia de la definición, incluso si el cuerpo de la función contiene operando no dependiente de tipo.

 24
Author: Sebastian Redl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-12 10:22:11