Boost.Spirit 使用的这个不寻常的 C++ 模板功能的名称是什么?
What is the name of this unusual C++ template feature used by Boost.Spirit?
以下代码来自Boost.Spirit x3 documentation。它使用了一种我以前从未见过的有趣的 C++ 语法,如果不知道正确的术语,几乎不可能在搜索查询中对其进行描述。 shorthand 是为了 class 的前向声明吗? 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);
}
模板的参数不一定要定义才能使用。使用 "class roman" 实际上声明了 class 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;
}
正如人们在上面的评论中指出的那样,这区分了模板的实例化。为了直接回答您的问题,在模板实例化中指定模板参数的性质称为 'elaborated type specifier'.
等同于:
class roman;
x3::rule<roman, unsigned> const roman = "roman";
换句话说,在需要 typename 的地方写 class T
,首先声明 T
是 class 的名称,然后继续 T
作为用于表达式其余部分的类型名称。
请注意,在 C++ 中,类型名 roman
和此处声明的变量名 roman
之间没有冲突;这是允许的。
另一种情况可能在没有模板的情况下发生,例如:
void func( class bar *ptr );
如果未声明 [=17=],则 是正确的;它声明 bar
,然后声明函数以获取指向 bar
.
的指针
以下代码来自Boost.Spirit x3 documentation。它使用了一种我以前从未见过的有趣的 C++ 语法,如果不知道正确的术语,几乎不可能在搜索查询中对其进行描述。 shorthand 是为了 class 的前向声明吗? 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);
}
模板的参数不一定要定义才能使用。使用 "class roman" 实际上声明了 class 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;
}
正如人们在上面的评论中指出的那样,这区分了模板的实例化。为了直接回答您的问题,在模板实例化中指定模板参数的性质称为 'elaborated type specifier'.
等同于:
class roman;
x3::rule<roman, unsigned> const roman = "roman";
换句话说,在需要 typename 的地方写 class T
,首先声明 T
是 class 的名称,然后继续 T
作为用于表达式其余部分的类型名称。
请注意,在 C++ 中,类型名 roman
和此处声明的变量名 roman
之间没有冲突;这是允许的。
另一种情况可能在没有模板的情况下发生,例如:
void func( class bar *ptr );
如果未声明 [=17=],则 是正确的;它声明 bar
,然后声明函数以获取指向 bar
.