![]() |
1
995
为了分析C++程序,编译器需要知道某些名称是否为类型。以下示例说明:
这应该如何解析?对于许多语言来说,编译器不需要知道名称的含义,就可以解析和基本了解一行代码的作用。在C++中,以上所述可以根据不同的原因产生非常不同的解释。
编译器将如何确定名称
您可能建议等待用户实例化模板:
这将起作用,并且作为一种可能的实现方法被标准实际允许。这些编译器基本上将模板的文本复制到一个内部缓冲区中,并且只有在需要实例化时,才会解析模板并可能检测到定义中的错误。但是不要打扰模板的用户(可怜的同事!)对于模板作者所犯的错误,其他实现选择尽早检查模板,并在实例化发生之前尽快给出定义中的错误。 所以必须有一种方法来告诉编译器某些名称是类型,而某些名称不是。 “typename”关键字
答案是:
我们
决定编译器应该如何分析这个问题。如果
有很多名字
语法允许
类似的gotcha存在于表示模板的名称中,正如介绍性文本所暗示的那样。 “template”关键字记住上面的初始报价,以及标准如何要求对模板进行特殊处理?让我们以下面这个无辜的例子为例:
对于人类读者来说,这可能是显而易见的。对编译器来说不是这样。想象一下以下任意定义
这实际上是一个有效的
表达
!它使用小于运算符进行比较
现在我们又回到了同样的问题上
模板名称不能只出现在
依赖关系对于那些书架上有厚厚的标准书籍的人,如果他们想知道我到底在说什么,我会稍微谈一谈标准中如何规定这一点。 在模板声明中,根据用于实例化模板的模板参数,某些构造具有不同的含义:表达式可能具有不同的类型或值,变量可能具有不同的类型,或者函数调用可能最终调用不同的函数。这种构造通常被称为 依赖 在模板参数上。 标准通过构造是否依赖来精确定义规则。它将它们分成逻辑上不同的组:一个捕获类型,另一个捕获表达式。表达式可能取决于其值和/或类型。因此,我们附上了典型的例子:
大多数规则都是直观的,并且是递归构建的:例如,类型构造为
从属名
标准对什么有点不清楚
确切地
是一个
从属名
. 在一个简单的阅读(你知道,最不惊讶的原则)中,它定义为
从属名
以下是函数名的特殊情况。但很明显
为了避免这个问题,我对标准文本进行了简单的解释。在所有表示依赖类型或表达式的构造中,一个子集表示名称。因此,这些名称是“从属名称”。一个名字可以采用不同的形式-标准规定:
标识符只是一个简单的字符/数字序列,接下来的两个是
依赖于值的表达式
依赖函数名
主要不是本文关注的问题,但仍然值得一提:函数名是一个单独处理的异常。标识符函数名不依赖于它本身,而是依赖于调用中使用的依赖于类型的参数表达式。在这个例子中
附加说明和示例
在足够的情况下,我们需要
关键词
在某些情况下,禁止使用关键字,详情如下
|
![]() |
2
127
C++ 11问题
而C++ 03中的规则在你需要的时候
可以看出,我们需要消歧关键字,即使编译器能够很好地发现
电流实例化
为了改善这种情况,在C++ 11中,当一个类型引用封闭模板时,语言会跟踪。要知道,类型必须是通过使用某种形式的名称形成的,这是它自己的名称(在上面,
基于这个概念,语言说
关键词
这很令人印象深刻,但我们能做得更好吗?语言更进一步
要求
一个实现再次查找
在实例化时需要一个编译器来捕获错误
未知的专业
在代码中
想象一下如果我们有一个成员函数会发生什么
在C++ 03中,允许语言捕获此错误,因为永远不可能有实例化的有效方式。
示例和琐事你可以试试这个知识 this answer 看看上面的定义对你在现实世界中的例子是否有意义(在这个答案中,它们的重复稍微不那么详细)。 C++ 11规则使下面的有效C++ 03代码不正确(这不是C++委员会想要的,但可能不固定)。
这个有效的C++ 03代码将绑定
|
![]() |
3
81
目的是什么
|
![]() |
4
19
但是,我不确定您是否正确实现了inunion。如果我理解正确,这个类不应该被实例化,因此“fail”选项卡永远不会实际失败。也许最好用一个简单的布尔值来指示类型是否在联合中。
附言:看看 Boost::Variant PS2:看看 typelists 尤其是在Andrei Alexandrescu的书中:现代C++设计 |
![]() |
5
17
这个答案应该是一个相当简短和甜蜜的答案(部分)标题的问题。如果你想要一个更详细的答案来解释为什么你必须把它们放在那里,请去 here .
将
注意,这也适用于采用通用模板参数的元函数或事物。但是,如果提供的模板参数是显式类型,则不必指定
添加的一般规则
给定此结构和函数:
正在尝试访问
因此,在这种情况下,您需要
这样编译器就可以正确地分析这个问题,而不是
|
![]() |
6
2
我把杰博尔赫斯的优秀 response 从cplusplus.com逐字回答一个类似的问题,因为这是我读过的关于这个主题的最简洁的解释。
总结 仅在模板声明和定义中使用关键字type name,前提是您具有引用类型并依赖于模板参数的限定名称。 |
![]() |
GTAVLover · C++根据给定的类型名从变量返回数据 7 年前 |
![]() |
user3417339 · 类模板交互 11 年前 |
|
user2891951 · 依赖作用域中的typename 11 年前 |
![]() |
Rubens · C++类迭代器实用程序:定义和用法 12 年前 |