es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Clase de plantilla recursiva y error de instanciación implícita en C++.

El siguiente ejemplo mínimo reproducible contiene una plantilla “struct B” con un tipo de argumento predeterminado que contiene una lambda “A<[]{ return 1; }>”, “B” se hereda recursivamente de “B<>”. Y hay una especialización de “B” para cualquier “A“.

template<auto>
struct A{};

template<class = A<[]{ return 1; }>>
struct B : B<> {};

template<auto z>
struct B<A<z>> {};

B<int> x;

GCC está bien con el ejemplo, pero Clang se queja:
error: implicit instantiation of template 'B<A<{}>>' within its own definition
Demo: https://gcc.godbolt.org/z/xzjzo7dE9

¿Qué compilador tiene la razón aquí?

P.S. Si se modifica la definición de "B" de esta manera:
```cpp
template<class>
struct B : B<A<[]{ return 1; }>> {};

entonces todos los compiladores quedan completamente satisfechos, demo: https://gcc.godbolt.org/z/roqnc39eq

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El comportamiento en este caso es indefinido según el estándar de C++. La estructura de plantilla B se hereda recursivamente de B<> con un tipo de argumento predeterminado que contiene una lambda. Sin embargo, la especialización de B para cualquier A<z> se define antes de que la definición de B esté completa, por lo tanto, Clang se queja correctamente de esta instancia implícita dentro de su propia definición.

    La modificación realizada en B resuelve este problema mediante la introducción de una herencia no recursiva de B<a<[]{ return="" 1;="" }="">>. Por lo tanto, todos los compiladores están satisfechos con esta definición modificada de B.

    Vale la pena señalar que confiar en un comportamiento indefinido de esta manera puede llevar a resultados inesperados y se debe evitar en el código de producción.</a<[]{>

Comments are closed.