【问题标题】:'typename' and alias templates'typename' 和别名模板
【发布时间】:2015-05-12 03:11:25
【问题描述】:

以下代码编译using both Clang and GCC,即使Foo_t<T>::Bar前面没有typename

struct Foo {
    using Bar = int;
};

template<class...>
using Foo_t = Foo;

template<class T>
void f(){
    Foo_t<T>::Bar b; // No typename!
}

int main(){
    f<int>();
}

应该编译吗?

【问题讨论】:

  • 模板别名在使用时立即被替换,所以代码等价于template &lt;class T&gt; void f() { Foo::Bar b; },没有依赖名。

标签: c++ templates c++11 language-lawyer


【解决方案1】:

简介

Foo_t&lt;T&gt;::Bar 可能看起来像一个从属名称,但它不是因为传递给 alias-declarationtemplate-arguments 在确定什么时不使用qualified-id Bar 指的是。

代码格式正确。



标准 (N3337) 怎么说?

14.5.7/2 别名模板 [temp.alias]

当一个template-id指代一个别名模板的特化时,它等价于关联类型 通过将其 template-arguments 替换为别名的 type-id 中的 template-parameters 获得 模板。

A.6 声明 [gram.dcl]

alias-declaration:
  using identifier attribute-specifier-seq_opt = type-id ;


标准真正在说什么?

由于Foo_ttype-id中没有template-parameters,所以template alias-declaration总是直接等价的到Foo,无论我们传递什么模板参数

template<class... Ts>
using Foo_t = Foo;
//            ^--- "Foo" = type-id

Foo_t&lt;T&gt; 的用法替换为模板别名声明的等价物,我们得到以下结果:

template<class T>
void f(){
    Foo::Bar b; // ok, nothing here depends on `T`
}

【讨论】:

  • So [temp.dep.type]/p8 - “一个类型是依赖的,如果它是......一个 simple-template-id 其中......任何模板参数是依赖类型..." 仅适用于别名模板替换后的类型?
  • @T.C.别名声明中的 type-id 不是 simple-template-id
  • 不,我是说Foo_t&lt;T&gt; 是一个simple-template-id,它的模板参数之一,即T,是一个依赖类型。
  • @FilipRoséen-refp 可能,但它也是一个 simple-template-id,其中一个模板参数是依赖类型。因此,通过该子句,它 依赖类型。在别名模板子句下,它也等价于FooFoo 显然不是依赖类型。从表面上看,这似乎是一个矛盾。是否有明确的条款规定必须解决此矛盾以使其不是依赖类型?或者“等价”是什么意思?或者 [temp.dep.type]/p8 中是否有一些子条款指出“这不适用于此处”?
  • @Yakk 我回家后会回复并更新答案;相关措辞在标准中。 (写在我的黑莓手机上
【解决方案2】:

更多挖掘,这里是CWG issue 1390

问题描述是

根据 14.6.2.1 [temp.dep.type] 第 8 段,类型是依赖的 (除其他外)如果是

一个 simple-template-id,其中模板名称是一个模板 参数或任何模板参数是依赖类型或 类型相关或值相关的表达式

这适用于别名模板特化,即使结果 类型不依赖于模板参数:

struct B { typedef int type; };
template<typename> using foo = B;
template<typename T> void f() {
  foo<T>::type * x;  //error: typename required
}

是否有必要对此类案件的规则进行更改?

在那个问题中有一个注释:

2012 年 10 月会议记录:

CWG 同意在这种情况下不需要typename。在一些 方式,别名模板特化就像当前的 实例化,并且可以在模板定义时知道。

该问题仍处于“起草”状态,但编译器供应商似乎已经在实施预期的解决方案。

【讨论】:

  • 上述编译器供应商一直按照描述的方式实现它,据我所知,他们的实现反映了那个DR的内容。老实说,我觉得 DR 有点……嗯,“没有经过深思熟虑” - 标准有必要的措辞来在我的帖子中得出结论。
猜你喜欢
  • 2017-06-22
  • 2011-01-02
  • 2011-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-20
相关资源
最近更新 更多