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