c++ c++14 crtp return-type-deduction

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



c++14 crtp (1)

Considera 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 de devolución que depende de la firma del operator() en la clase derivada. Sin embargo, decltype(&Der::operator()) no puede compilarse; La función miembro de operator() en Foo no está visible. Supongo que esto se debe a que la plantilla de la clase base se instancia antes de que Foo esté completamente definido.

Sorprendentemente, si coloco el auto para el tipo de retorno compila. Supuse que el auto haría que el compilador deduzca el tipo de retorno del cuerpo de la función y falle, porque el cuerpo usa el tipo de 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 ? ¿La deducción auto tipo de alguna manera "retrasa" la instanciación? ¿O utilizar un contexto diferente al de una expresión de devolución escrita a mano?


Tu conjetura es correcta. Un tipo de retorno deducido no se deduce 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 del tipo de devolución 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 una declaración de devolución con un operando no dependiente del tipo.