Как называется эта необычная функция шаблона C++, используемая Boost.Дух?
приведенный ниже код от импульс.Документация Spirit x3. Он использует интересный синтаксис C++, который я никогда раньше не видела, который почти невозможно описать в поисковом запросе, не зная правильной терминологии. Является ли это сокращением для прямого объявления класса? Где эта функция упоминается в стандарте 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);
}
2 ответов:
аргументов шаблона не обязательно должны быть использованы. Использование "класса roman" фактически объявляет класс roman.
вот пример кода:
#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; }
как люди указали в комментариях выше, это отличает этот экземпляр шаблона. И чтобы напрямую ответить на вопрос, который у вас был, указание природы аргумента шаблона в экземпляре шаблона называется "разработанным спецификатором типа".
это то же, что:
class roman; x3::rule<roman, unsigned> const roman = "roman";
другими словами, пишет
class T
где ожидается имя типа, сначала объявляет, чтоT
- это имя класса, а затем сT
в качестве имени типа используется для остальной части выражения.обратите внимание, что в C++ нет никакого столкновения между typename
roman
и имя переменнойroman
объявляется здесь; это разрешено.
другой случай этого может произойти без шаблонов, например:
void func( class bar *ptr );
является правильным, если
bar
необъявленный; он объявляетbar
а затем объявляет функцию, чтобы взять указатель наbar
.
Comments