¿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?
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.
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