使用带有typedef和new的typename关键字 [英] Use of typename keyword with typedef and new

查看:154
本文介绍了使用带有typedef和new的typename关键字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑此代码,

template<class T>
struct Sample
{ 
     typename T::X *x; //declare pointer to T's X
};

在上面的代码中,关键字 typename 是编译器需要的,以便它可以消除模板中的嵌套类型和嵌套值之间的歧义。这意味着,在没有 typename 关键字的情况下,编译器会将此解释为T :: X与x的乘法,

In the above code, the keyword typename is required by the compiler, so that it can disambiguate between nested types and nested values in templates. That means, in the absence of typename keyword, compiler would interpret this as multiplication of T::X with x,

T::X *x; //multiply T::X with x

因此,在出现歧义的情况下, code> typename 变为必要,以消除歧义。但是,上下文本身消除歧义的情况很少。 其他主题讨论了基类和函数调用的上下文,参数(后者不会消除歧义)。在这个主题中,我特别想讨论看起来是明确的其他两个上下文,但我们仍然需要写 typename



So in such situations where ambiguity can arise, the keyword typename becomes necessity so as to remove ambiguities. But there are few situations when the context itself removes ambiguities. The other topic discusses contexts of base-class and function-parameters (the latter doesn't remove ambiguity though). In this topic, I particularly want to discuss other two contexts which seem to be unambiguous, but we're still required to write typename,

typedef typename T::X xtype;
pX = new typename T::X;  

在这两种情况下,关键字 typedef new 使得对编译器足够清楚,以下是类型 >。

In these two situations, the keywords typedef and new make it clear enough to the compiler that whatever follows is type, not value.

所以我的问题是,为什么编译器仍然需要 typename 关键字,即使在明确的情况下,使用 typedef

So my question is, why do compilers still need the typename keyword, even in unambiguous situations such as when we use typedef and new?

//typedef NOT followed by a type!
int typedef A;

此语法要求我修改我的问题一点,做,可以被别人看到。

This syntax asks me to modify my question a little bit, so that the point which I'm trying to make, may be seen by others.

考虑这个,

T::X typedef *x;

所以从上下文来看,对于编译器来说,T :: X是一个类型,无论是在之前 typedef 还是之后 typedef 除非C ++允许我们写 typedef 5 five typedef T :: value t_value value是 value ), typedef 本身删除所有模糊,因此 typename 似乎是标准(在这种情况下)不必要的要求。相同的参数也适用于 new

So from the context, it's still clear enough to the compiler that T::X is a type, no matter whether it appears before typedef,or after typedef. Unless C++ allows us to write typedef 5 five or typedef T::value t_value (where T::value is value), the presence of typedef itself removes all ambiguities and so, typename seems to be an unnecessary requirement by the Standard (in such situations). Same argument holds true for new as well.

我写了一个类模板,它使用这个struct作为模板参数:

Also, I've written a class template which is using this struct as template argument:

struct A 
{
        struct X { string name; };
        static const int X = 100;
};

我特别想知道下面的代码(从构造函数)是否正确,

I particularly want to know if the following code (from the constructor) is correct (portable) or not,

//two interesting statements
 pX = new typename T::X; //T::X means struct X
 product = T::X * p; //but here, T::X means int X

完整的代码是在这里在ideone。请回复之前看看它。 : - )

The complete code is here at ideone. Please have a look at it before replying. :-)

推荐答案

C ++语法比这更疯狂。

C++ syntax is more crazy than that.

// typedef NOT followed by a type!
int typedef A;

// new NOT followed by a type!
new (0) int;

其他人对您的示例发表了评论。 typename 说明符不会忽略非类型名称的查找。所以如果你说新的类型名T :: X ,并且在 X > T ,仍会找到它,而不是类型名称 X (GCC忽略非类型名称, code> typename ,但这不符合标准)。

Others have commented about your example. The typename specifier does not yield to lookup ignoring non-type names. So if you say new typename T::X, and there is an object name X in T, it will still be found instead of the type name X (GCC however ignores non-type names in looking up a name after a typename. But that's not Standards compliant).

编辑回答

考虑这个,

T::X typedef *x;

所以从上下文看来,对于编译器来说,T :: X是一个类型,无论是在typedef之前还是在typedef之后。

So from the context, it's still clear enough to the compiler that T::X is a type, no matter whether it appears before typedef,or after typedef.

编译器必须知道何时声明说明符和部分和声明部分开始时(即名称部分)。声明中类型部分为空:

The compiler has to know when the declaration specifiers and (i.e the "type section" and when the declarator section start (i.e the "names" section). There are declarations where the type section is empty:

// constructor definitions don't need a type section
MyClass::MyClass() { }

// conversion function definitions don't need a type section
MyClass::operator int() { }



如果指定的名字不是类型,结束,名称段开始。 T :: X 告诉编译器:


现在我想定义 T :: X

从左到右,所以它会认为你忘了一个分号,当它遇到 typedef 。内部类,解释略有不同,但也很喜欢这样。这是一个简单有效的解析。

It reads from left to right, so it will think you forgot a semicolon when it then encounters the typedef. Inside classes the interpretation is slightly different but much like this too. That's a simple and effective parse.


同样的参数也适用于新的。

Same argument holds true for new as well.

我在这里同意你的意见。在语法上,它应该是明确的如果你离开括号。因为我从来没有写过一个C ++解析器,可能有隐藏的陷阱,我没有看到,虽然。

I tend to agree with you here. Syntactically it should be unambiguous if you leave off parentheses. As I've never written a C++ parser, there may be hidden pitfalls I'm not seeing, though.

中添加 typename c $ c>对于编译器和标准作者可能需要大量的设计,而对于需要它的绝大多数其他情况仍然需要 typename 。我不认为这是值得的。

Every addition of typename in corner cases of the language like in new will potentially require substantial amount of design for both compilers and standards writers, while still requiring typename for the vast majority of other cases where it's needed. I don't think that this pays off.

这篇关于使用带有typedef和new的typename关键字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆