【发布时间】:2011-05-24 04:57:48
【问题描述】:
考虑这段代码,
template<class T>
struct Sample
{
typename T::X *x; //declare pointer to T's X
};
在上面的代码中,关键字typename是编译器需要的,这样可以消除模板中嵌套类型和嵌套值的歧义。这意味着,在没有 typename 关键字的情况下,编译器会将其解释为 T::X 与 x 的乘积,
T::X *x; //multiply T::X with x
所以在这种可能出现歧义的情况下,关键字typename变成必要性,以消除歧义。但是,上下文本身消除歧义的情况很少。 other topic 讨论了基类和函数参数的上下文(尽管后者并没有消除歧义)。在这个话题中,我特别想讨论其他两个似乎明确,但我们仍然需要写typename,
typedef typename T::X xtype;
pX = new typename T::X;
在这两种情况下,关键字typedef 和new 足以让编译器清楚地知道后面的内容是type,不是 value。
所以我的问题是,为什么编译器仍然需要 typename 关键字,即使在明确的情况下,例如我们使用 typedef 和 new 时?
编辑(阅读Johannes Schaub的回复后):
//typedef NOT followed by a type!
int typedef A;
这种语法要求我稍微修改一下我的问题,以便其他人可以看到我试图提出的观点。
考虑一下,
T::X typedef *x;
所以从上下文来看,编译器仍然很清楚 T::X 是一种类型,无论它出现在 before typedef 还是 after typedef。 除非 C++ 允许我们编写 typedef 5 five 或 typedef T::value t_value(其中 T::value 是 value),typedef 本身的存在消除了所有歧义,因此,typename 似乎是标准的不必要要求(在这种情况下)。同样的论点也适用于new。
另外,我编写了一个类模板,它使用这个结构作为模板参数:
struct A
{
struct X { string name; };
static const int X = 100;
};
我特别想知道下面的代码(来自构造函数)是否正确(可移植),
//two interesting statements
pX = new typename T::X; //T::X means struct X
product = T::X * p; //but here, T::X means int X
完整的代码是 here at ideone。回复前请看一下。 :-)
【问题讨论】:
-
他的问题是为什么编译器在
typedef之后需要一个typename关键字。因为在typedef之后,它总是知道 typeString 是 Commin。但是我认为这就是语法分析器的编写方式。 -
@Pawel :问题是:为什么编译器在明确的情况下仍然需要 typename 关键字?
-
这是编写语法的规则。真的需要从中做出意义吗?即使在 typedef 之后出现的也应该是一种类型。所以你必须键入它。编译器在 typedef 获得类型之后永远不知道。相反,它期望下一个标记是一个类型。并且 typename 证实了这一点。
-
@user256007 :你的理由对我来说并不令人信服,因为如果在 typedef 编译器之后没有找到类型,那么它会给出编译错误,就像你也使用 typename 一样。跨度>
-
@Nawaz:显然编译器不需要它。看看 MSVC! :)
标签: c++ templates typedef language-lawyer typename