【问题标题】:Is it C++ standard-compliant to define a variable using `A<int>::template B<int> x;`? [duplicate]使用 `A<int>::template B<int> x;` 定义变量是否符合 C++ 标准? [复制]
【发布时间】:2014-08-25 22:45:56
【问题描述】:

以下代码被 gcc、vc++、clang 接受。

template<class T>
struct A
{
    template<class U>
    struct B
    {};
};

int main()
{
    A<int>::B<int> y; // OK as expected
    A<int>::template B<int> x; // Also OK! Is this standard-compliant?
};

使用A&lt;int&gt;::template B&lt;int&gt; x;定义变量是否符合C++标准?

【问题讨论】:

  • B 是依赖于模板的类型模板,所以第二种语法完全正确。
  • 您能否让我参考指定此用法的标准页面?谢谢。
  • @peppe 不是重复的,因为这里不需要使用template
  • @MikeSeymour 哦。因此,只有A&lt;W&gt;::template B&lt;int&gt; 在具有模板参数W 的范围内才会出现这种情况?
  • @Quentin:确实;当名称的解释取决于未知的模板参数时,在依赖的上下文中需要它。在这里,不需要它,因为模板已经专门化了,我们确切地知道B 在那个专门化中是什么。 (对不起,我有短暂的第二个想法,并删除了我的评论,说它不依赖于这里)。

标签: c++ templates c++11 compiler-construction portability


【解决方案1】:

虽然是非规范性注释,但我认为 n3797[temp.names]/6 可以给出答案

typename 前缀一样,template 前缀在并非绝对必要的情况下是允许的;即,当 nested-name-specifier-&gt;. 左侧的表达式不依赖于模板参数,或使用未出现在一个模板。

在OP的例子中,前缀template是在模板范围之外使用的,并且前面的nested-name-specifier是不依赖的。因此,前缀template 不是必需的,但此处允许使用。


[expr.prim.general]/8

合格 ID
nested-name-specifier templateoptunqualified-id

加上 [temp.names]/5

以关键字template 为前缀的名称应为template-id,或者该名称应引用类模板。

[temp.names]/1 表示B&lt;int&gt; 确实是一个 (simple-)template-id

【讨论】:

  • 这一切都适用于 C++11+,不适用于 C++98/03。我说的对吗?
  • @Constructor 在 C++03 中,即使 nested-type-name 不依赖,您也可以使用关键字 template;但是你不能在模板范围之外使用它。
猜你喜欢
  • 2014-11-09
  • 1970-01-01
  • 2015-03-20
  • 2021-11-21
  • 2018-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-19
相关资源
最近更新 更多