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.

¿Es posible inicializar la clase interna de una plantilla en la cláusula “requires” de C++20?

Considere la siguiente clase A que define una clase interna de plantilla B:

struct A {
  template<class =="" int="">
  struct B { };
};

Podemos usar la siguiente expresión para inicializar la clase interna B, donde typename es opcional: (Godbolt)

int main() {
  A::template B<>();
  typename A::template B<>();
}

Quiero usar conceptos para detectar si un tipo tiene una clase interna de plantilla B:

template<class t="">
concept C = requires {
  typename T::template B<>();
};

static_assert(C<a>);

Pero solo clang aceptó el código anterior, GCC y MSVC lo rechazaron debido a un error de sintaxis (Godbolt):

<source>:8:27: error: expected ';' before '(' token
    8 |   typename T::template B<>();
      |                           ^
      |                           ;

Y si elimino el typename en la cláusula require:

template<class t="">
concept C = requires {
  T::template B<>();
};

MSVC lo acepta, pero Clang y GCC producirán una “declaración de aserción estática fallida” ya que consideran que la expresión no está bien formada (Godbolt):

<source>:11:15: note: because 'A' does not satisfy 'C'
static_assert(C<a>);
              ^
<source>:8:15: note: because 'T::template B<>()' would be invalid: 'A::B' instantiated to a class template, not a function template
  T::template B<>();
              ^

¿En qué compilador debería confiar?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Sin más información sobre el caso de uso específico y el comportamiento deseado, es difícil decir qué compilador es correcto. Es posible que un compilador siga más estrictamente la norma C++20 o que haya implementado ciertas características de manera diferente. También es posible que haya un error en uno o más de los compiladores.

    En general, se recomienda escribir código que sea portable y funcione en varios compiladores, especialmente para código de bibliotecas o frameworks que pueda ser utilizado por otros. Esto se puede lograr mediante pruebas del código en varios compiladores, verificando su cumplimiento con el estándar y evitando depender de comportamientos específicos de la implementación.

    Si el comportamiento deseado del código está claro y bien definido, puede ser útil informar cualquier inconsistencia o problema con los compiladores a sus respectivos desarrolladores o comunidades.

Comments are closed.