- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在模板中,为什么必须在哪里以及为什么要将typename
和template
放在从属名称上?
无论如何,依赖名称到底是什么?
我有以下代码:
template <typename T, typename Tail> // Tail will be a UnionNode too.
struct UnionNode : public Tail {
// ...
template<typename U> struct inUnion {
// Q: where to add typename/template here?
typedef Tail::inUnion<U> dummy;
};
template< > struct inUnion<T> {
};
};
template <typename T> // For the last node Tn.
struct UnionNode<T, void> {
// ...
template<typename U> struct inUnion {
char fail[ -2 + (sizeof(U)%2) ]; // Cannot be instantiated for any U
};
template< > struct inUnion<T> {
};
};
typedef Tail::inUnion<U> dummy
行中。我相当确定
inUnion
是一个从属名称,而VC++恰好可以使它窒息。
template
来告诉编译器inUnion是一个模板ID。但是到底在哪里?然后是否应该假设inUnion是一个类模板,即
inUnion<U>
命名一个类型而不是一个函数?
最佳答案
(请参阅here also for my C++11 answer)
为了解析C++程序,编译器需要知道某些名称是否为类型。以下示例说明了这一点:
t * f;
t
的含义,以上内容可能会产生截然不同的解释。如果是类型,则它将是指针
f
的声明。但是,如果不是类型,它将是一个乘法。因此,C++标准在第(3/7)段中说:
Some names denote types or templates. In general, whenever a name is encountered it is necessary to determine whether that name denotes one of these entities before continuing to parse the program that contains it. The process that determines this is called name lookup.
t::x
引用模板类型参数,编译器将如何找出
t
引用的名称?
x
可以是一个静态的int数据成员,可以乘以,也可以是可以产生声明的嵌套类或typedef。
如果名称具有此属性-在知道实际的模板参数之前无法查找,则该名称称为从属名称(“取决于”模板参数)。
Let's wait until the user instantiates the template, and then later find out the real meaning of
t::x * f;
.
t::x
是从属名称,那么我们需要给它加上
typename
前缀,以告诉编译器以某种方式对其进行解析。标准在(14.6 / 2)中说:
A name used in a template declaration or definition and that is dependent on a template-parameter is assumed not to name a type unless the applicable name lookup finds a type name or the name is qualified by the keyword typename.
typename
,因为编译器可以使用模板定义中的适用名称查找来弄清楚如何解析结构本身-例如,当
T *f;
是类型模板参数时,使用
T
。但是要使
t::x * f;
成为声明,必须将其写为
typename t::x *f;
。如果省略关键字,并且名称被视为非类型,但是当实例化发现它表示类型时,编译器会发出通常的错误消息。有时,错误因此在定义时给出:
// t::x is taken as non-type, but as an expression the following misses an
// operator between the two names or a semicolon separating them.
t::x f;
typename
-因此,可以认为,已知非合格名称总是引用类型。
boost::function< int() > f;
boost::function
和
f
的任意定义:
namespace boost { int function = 0; }
int main() {
int f = 0;
boost::function< int() > f;
}
boost::function
与零(
int()
)进行比较,然后使用大于运算符将结果
bool
与
f
进行比较。但是,您可能知道,
boost::function
in real life是模板,因此编译器知道(14.2 / 3):
After name lookup (3.4) finds that a name is a template-name, if this name is followed by a <, the < is always taken as the beginning of a template-argument-list and never as a name followed by the less-than operator.
typename
相同的问题。如果在解析代码时我们还不知道名称是否是模板怎么办?根据
template
的指定,我们需要在模板名称之前插入
14.2/4
。看起来像:
t::template f<int>(); // call a function template
::
之后,而且可以出现在
->
或
.
之后。您也需要在其中插入关键字:
this->template f<int>(); // call a function template
T
)N
)(T)0
的转换)T[N]
是值相关的表达式或
N
是相关类型,则构造为
T
的类型是相关类型。有关详细信息,请参见
(14.6.2/1
)(用于依赖类型),
(14.6.2.2)
(用于类型依赖的表达式)和
(14.6.2.3)
(用于值依赖的表达式)。
T::x
,因此它也必须是从属名称(很幸运,从C++ 14开始,委员会已经开始研究如何解决这个令人困惑的定义)。
A name is a use of an identifier (2.11), operator-function-id (13.5), conversion-function-id (12.3.2), or template-id (14.2) that denotes an entity or label (6.6.4, 6.1)
operator +
和
operator type
形式。最后一种形式是
template-name <argument list>
。所有这些都是名称,按照标准中的常规用法,名称还可以包含限定符,该限定符表示应查找名称的 namespace 或类。
1 + N
不是名称,但
N
是名称。所有相关构造的子集即名称都称为相关名称。但是,函数名称在模板的不同实例中可能具有不同的含义,但是不幸的是,该通用规则没有捕获函数名称。
f((T)0)
中,
f
是从属名称。在标准中,这是在
(14.6.2/1)
处指定的。
typename
和
template
。您的代码应如下所示
template <typename T, typename Tail>
struct UnionNode : public Tail {
// ...
template<typename U> struct inUnion {
typedef typename Tail::template inUnion<U> dummy;
};
// ...
};
template
不一定总是出现在名称的最后部分。它可以出现在用作范围的类名的中间,如以下示例所示
typename t::template iterator<int>::value_type v;
typename
。假定给定的名称是类类型名称。对于基类列表和构造函数初始化器列表中的名称都是如此: template <typename T>
struct derive_from_Has_type : /* typename */ SomeBase<T>::type
{ };
template
之后使用::
,并且C++委员会said不能解决问题。 template <typename T>
struct derive_from_Has_type : SomeBase<T> {
using SomeBase<T>::template type; // error
using typename SomeBase<T>::type; // typename *is* allowed
};
关于c++ - 为什么必须在哪里放置 “template”和 “typename”关键字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44944760/
template struct List { }; template class> struct ListHelper; template struct ListHelper> { };
最近,我注意到 html/template.Template 的 Templates() 与 text/template.Template 的工作方式不同。 // go1.12 func main()
我正在尝试使用 polymer 1.0 实现一个网站。我有一个自定义元素 my-greeting,里面有一些模板重复。 我想做的是获取一个名为 TARGET 的字符串,但我不知道该怎么做: /cons
(是的,由于我糟糕的英语,标题很奇怪;我希望有人能改进它。) 接听this question ,我发现这段代码有效: template class A { }; template class U>
这个问题在这里已经有了答案: How to import and use different packages of the same name (2 个答案) 关闭 4 年前。 我正在使用 Go
我的想法是这是不可能的,或者我缺少一个额外的步骤。无论哪种方式,我都被卡住了,无法弄清楚。 使用内联模板的原因是能够使用 Laravel Blade 语法并结合 Vue Js 的强大功能。似乎是两者中
我已经尝试实现一个“模板模板模板”——模板类来满足我的需求(我对使用模板元编程很陌生)。不幸的是,我发现以下主题为时已晚: Template Template Parameters 不过,我需要实现如
Helm _helpers.tpl? Helm 允许使用 Go templating在 Kubernetes 的资源文件中。 一个名为 _helpers.tpl 的文件通常用于定义 Go 模板助手,语
{{template "base"}} 和 {{template "base".}} 有什么区别? 我用的是go-gin,两者都可以正常运行。我在文档中找不到关于此的任何描述。 最佳答案 来自 god
我有一个本质上充当查找表的函数: function lookup(a::Int64, x::Float64, y::Float64) if a == 1 z = 2*x + y else if a =
当 out 成员函数(来自模板和特化)都需要模板时,为什么 c++ 需要模板参数,因为我没有得到它,谷歌也没有帮助。必须是c++11但和c++1z有同样的错误。 我正在使用 g++ 7.3.0 收到此
我正在寻找简单的方法来将带有 ${myvar} 的简单模板转换为带有 {{ myvar }} 的 GO 模板。 是否有任何库可以实现这一点? 最佳答案 使用正则表达式查找 \${([a-z0-9\_\
我有这个模板可以将 slice 的多个项目解析到页面上。它确实做得很好。 但是,我现在想使用完全相同的模板来根据范围索引解析 slice 的单个值。该 slice 在多个文件中使用,所以我不能像 Sl
要清理模板文件夹,我想将常用模板保存在子文件夹中。目前我有以下文件结构: main.go templates/index.tpl # Main template for the
最近我设计了元类型和允许编译时类型连接的可能操作: #include template typename T> struct MetaTypeTag {}; /*variable template
准备模板时发生错误。谁能告诉你怎么修? 如有必要,还可以编辑变量。 vars: AllСountry: - "name1" - "name2"
我在使用新的匿名模板引擎时遇到问题。它不能使用嵌套模板。我收到错误消息:“此模板引擎不支持嵌套在其模板中的匿名模板”。 我的问题:我如何强制 knockout JS 使用jquery 模板引擎,而不是
这个问题在这里已经有了答案: Where and why do I have to put the "template" and "typename" keywords? (8 个答案) 关闭 8
我在 C++ 中使用带有模板的集合: template class OMSSVDisk : public OMSSObjProperties{ set memberPDs; }; 如上面代码中
因为我喜欢分离接口(interface)和实现,而不是只在头文件中实现模板类,我将它分成 .h 和 .tpp(.tpp 这样它就不会用 *.cpp 编译)。然后我将 tpp 包含在头文件的末尾,就在
我是一名优秀的程序员,十分优秀!