Quel est le nom de cette fonctionnalité de modèle C ++ inhabituelle utilisée par Boost.Spirit?

Le code ci-dessous provient de la documentation Boost.Spirit x3 . Il utilise une syntaxe C ++ intéressante que je n’avais jamais vue auparavant, ce qui est presque impossible à décrire dans une requête de recherche sans connaître la terminologie appropriée. Est-ce un raccourci pour la déclaration en avant d’une classe? Où cette fonctionnalité est-elle mentionnée dans le standard 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 const roman = "roman"; // ^^^^^^^^^^^ auto const roman_def = eps [set_zero] >> ( -(+lit('M') [add1000]) >> -hundreds [add] >> -tens [add] >> -ones [add] ) ; BOOST_SPIRIT_DEFINE(roman); } 

Les arguments d’un modèle ne doivent pas nécessairement être définis pour être utilisés. L’utilisation de “class roman” déclare en fait la classe roman.

Voici un exemple de code:

 #include  template  void foo(); template<> void foo() { // 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; } 

Comme le soulignent les commentaires ci-dessus, cela distingue cette instanciation du modèle. Et pour répondre directement à la question que vous vous êtes posée, la spécification de la nature de l'argument du modèle dans une instanciation de modèle est appelée «spécificateur de type élaboré».

C’est la même chose que:

 class roman; x3::rule const roman = "roman"; 

En d’autres termes, l’écriture de la class T où un nom de type est attendu, déclare d’abord que T est le nom d’une classe, puis procède à T comme nom de typage utilisé pour le rest de l’expression.

Notez qu’en C ++, il n’y a pas de conflit entre le nom de fichier roman et le nom de variable roman déclaré ici; c’est permis.


Un autre cas peut se produire sans modèles, par exemple:

 void func( class bar *ptr ); 

est correct si la bar n’est pas déclarée; il déclare la bar et déclare ensuite la fonction de prendre un pointeur sur la bar .