模板模板成员的消歧器模板关键字:什么时候? [英] Disambiguator template keyword for a template member of a template: when exactly?
问题描述
此处提供了有关模板消除歧义的问题:
A question regarding template disambiguator was given here:
,在答案中我们可以阅读:
and in the answer we can read:
ISO C ++ 03 14.2 / 4
ISO C++03 14.2/4
或者在后缀表达式中,或者在限定id中的嵌套名称说明符之后,并且postfix-expression或qualified-id显式地取决于模板参数(14.6.2),成员模板名称必须是前缀为关键字模板。
When the name of a member template specialization appears after . or -> in a postfix-expression, or after nested-name-specifier in a qualified-id, and the postfix-expression or qualified-id explicitly depends on a template-parameter (14.6.2), the member template name must be prefixed by the keyword template. Otherwise the name is assumed to name a non-template.
现在这里是我的conrete例子,我不太明白: / p>
Now here comes my conrete example that I don't quite understand:
template <class T>
class Base {
public:
template <int v>
static int baseGet() {return v;}
class InnerA {
public:
template <int v>
static int aget() {return v;}
};
class InnerB {
public:
typedef Base BaseType;
typedef BaseType::InnerA OtherType;
template <int v>
static int baseGet() {return BaseType::baseGet<v>();} //(A)
template <int v>
static int aget() {return OtherType::aget<v>();} //(B)
};
};
这显然无法编译。您在行(B)中需要模板
: OtherType :: template aget< v>();
。
然而,g ++(4.4.3)和clang ++(2.9)都没有抱怨在行(A)中缺少模板
。为什么? BaseType
取决于类型 T
,不是吗?
It obviously fails to compile. You need template
in the line (B): OtherType::template aget<v>();
.
However, both g++ (4.4.3) and clang++ (2.9) don't complain about the lack of template
in the line (A). Why? BaseType
depends on the type T
, does it not? Is it a small depart from the standard by those compilers, or do I misunderstand something in the standard?
推荐答案
它们实现了C语言++ 0x规范,其中 Base
是当前实例化。在这种情况下,C ++ 0x允许省略模板
关键字。因为 BaseType
是 Base
的typedef,当您说 BaseType
,也命名当前实例化。
They implement the C++0x specification, where Base
is the current instantiation. And C++0x allows to omit template
keyword in such a case. Since BaseType
is a typedef for Base
, when you say BaseType
, that names the current instantiation too.
引用规范,因为你似乎对spec refs感兴趣
To quote the spec, since you seem to be interested in spec refs
名称是<...>
A name is a member of the current instantiation if it is [...]
- 的成员 id,其中嵌套名称指定符指向当前实例化,并且当查找时,指代当前实例化的至少一个成员或其非依赖基类。
- A qualified-id in which the nested-name-specifier refers to the current instantiation and that, when looked up, refers to at least one member of the current instantiation or a non-dependent base class thereof.
和
名称是指当前实例化,如果它是[...]
A name refers to the current instantiation if it is [...]
- 定义类模板的[...] 嵌套类,[...],类模板的注入类名(第9条)嵌套类
- in the definition of a [...] nested class of a class template, [...], the injected-class-name (Clause 9) of the class template or nested class
和(您修改的14.2 / 4)
$ b
and (the modified 14.2/4 that you quoted)
[...]或qualified-id中的nested-name-specifier是指依赖类型,但该名称不是当前实例化的成员(14.6.2.1),成员模板名称必须以关键字模板为前缀。 [...]
[...] or the nested-name-specifier in the qualified-id refers to a dependent type, but the name is not a member of the current instantiation (14.6.2.1), the member template name must be prefixed by the keyword template. [...]
注意:在C ++ 03中,因为 BaseType
和 OtherType
是相关的。规格说明:
Note: In C++03 your code is ill-formed because both BaseType
and OtherType
are dependent. The spec says:
一个类型是依赖的,如果它是[...]
A type is dependent if it is [...]
- 一个模板参数
- 一个具有嵌套名称说明符的限定ID,其中包含命名依赖类型的类名
- 一个template-id,其中模板名称是模板参数或任何模板参数是依赖类型
(注意 Base
等效于 Base< T>
这是 Base
和 BaseType :: InnerA
是依赖类型的基础)。
(note that Base
is equivalent to Base<T>
, which is the base on which Base
and BaseType::InnerA
are dependent types).
请注意,您的报价中的明确依赖是一个预标准术语,并且最近被清除了(我相信是在1996年12月)。它基本上意味着(在这个上下文中)限定符是依赖的限定符,或者是一个类成员访问( a-> x
/
)其中 a
是依赖。在显式依赖从草稿中删除后,它仍然潜伏在一些地方,甚至C ++ 0x仍然引用显式依赖在14.6.2p2的注释:
Note that "explicitly depends" in your quote is a pre-standard term, and was gotten rid of fairly lately (I believe it was at December1996). It basically meant (in this context) a qualified-id in which the qualifier is dependent or a class member access (a->x
/ a.x
) where the a
was dependent. After "explicitly depends" was removed from the draft, it was still lurking around at some places, and even C++0x has still references to "explicitly depends" in a note at 14.6.2p2:
基类名
B
,类型名T :: A
,名称B
和:: i pb-> j
显式依赖。
the base class name
B<T>
, the type nameT::A
, the namesB<T>::i
andpb->j
explicitly depend on the template-parameter.
这篇关于模板模板成员的消歧器模板关键字:什么时候?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!