operator - ¿Cuál es el nombre de esta característica de plantilla de C++ inusual utilizada por Boost.Spirit?
overload c++ operator (2)
Es lo mismo que:
class roman;
x3::rule<roman, unsigned> const roman = "roman";
En otras palabras, al escribir la
class T
donde se espera un nombre de tipo, primero declara que
T
es el nombre de una clase, y luego continúa con
T
como el nombre de tipo que se usa para el resto de la expresión.
Tenga en cuenta que en C ++ no hay conflicto entre el nombre de tipo
roman
y el nombre de variable
roman
se declara aquí;
Eso está permitido.
Otro caso de esto puede suceder sin plantillas, por ejemplo:
void func( class bar *ptr );
es correcto si la
bar
no está declarada;
declara
bar
y luego declara la función para tomar un puntero a
bar
.
El siguiente código es de la documentación de Boost.Spirit x3 . Utiliza una sintaxis interesante de C ++ que nunca he visto antes, que es casi imposible de describir en una consulta de búsqueda sin conocer la terminología adecuada. ¿Es esta abreviatura para la declaración adelantada de una clase? ¿Dónde se menciona esta característica en el estándar C ++?
namespace parser
{
using x3::eps;
using x3::lit;
using x3::_val;
using x3::_attr;
using ascii::char_;
auto set_zero = [&](auto& ctx){ _val(ctx) = 0; };
auto add1000 = [&](auto& ctx){ _val(ctx) += 1000; };
auto add = [&](auto& ctx){ _val(ctx) += _attr(ctx); };
// What is this? This is the very first use of the identifier `roman`.
x3::rule<class roman, unsigned> const roman = "roman";
// ^^^^^^^^^^^
auto const roman_def =
eps [set_zero]
>>
(
-(+lit(''M'') [add1000])
>> -hundreds [add]
>> -tens [add]
>> -ones [add]
)
;
BOOST_SPIRIT_DEFINE(roman);
}
Los argumentos de una plantilla no necesariamente tienen que definirse para ser utilizados. El uso de "clase romana" en realidad declara la clase romana.
Aquí hay un código de ejemplo:
#include <iostream>
template <class T> void foo();
template<> void foo<class roman>()
{
// allowed because roman is declared
roman* pointer1;
// not allowed because romania is not declared
// romania* pointer2;
std::cout << "Hello world!" << std::endl;
return;
}
int main(int argc, char** argv) {
return 0;
}
Como la gente ha señalado en los comentarios anteriores, esto distingue esta instanciación de la plantilla. Y para responder directamente a la pregunta que tenía, la especificación de la naturaleza del argumento de plantilla en una instanciación de plantilla se denomina ''especificador de tipo elaborado''.