Как называется эта необычная функция шаблона 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);
}
526   2  

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

    Ничего не найдено.