简体   繁体   English

'typename'和别名模板

[英]'typename' and alias templates

The following code compiles using both Clang and GCC , even though Foo_t<T>::Bar doesn't have typename in front of it: 下面的代码使用Clang和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>();
}

Should it compile? 它应该编译吗?

Introduction 介绍

Foo_t<T>::Bar might look like a dependent-name, but it isn't since the template-arguments passed to the alias-declaration are not used when determining what the qualified-id Bar is referring to. Foo_t<T>::Bar可能看起来像一个依赖名称,但它不是因为在确定qualified-id Bar引用的内容时不会使用传递给alias-declarationtemplate-arguments

The code is well-formed. 代码格式正确。



What does the Standard ( N3337 ) say? 标准( N3337 )说什么?

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

When a template-id refers to the specialization of an alias template, it is equivalent to the associated type obtained by substitution of its template-arguments for the template-parameters in the type-id of the alias template. template-id引用别名模板的特化时,它等同于通过替换别名模板的type-id中的template-parameters的 template-arguments获得的关联类型。

A.6 Declarations [gram.dcl] A.6 声明 [gram.dcl]

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


What is the Standard really saying? 标准真正说的是什么?

Since there are no template-parameters in the type-id of Foo_t , the template alias-declaration is always directly equivalent to Foo , no matter what template-arguments we pass to it. 由于Foo_ttype-id中没有模板参数 ,因此模板alias-declaration总是直接等效于Foo ,无论我们传递给它的是什么模板参数

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

Replacing the usage of Foo_t<T> with the equivalence of the template alias-declaration leaves us with the following: 模板别名声明的等价替换Foo_t<T>的用法使我们得到以下内容:

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

With some more digging, this is CWG issue 1390 . 通过更多挖掘,这是CWG问题1390

The issue description is 问题描述是

According to 14.6.2.1 [temp.dep.type] paragraph 8, a type is dependent (among other things) if it is 根据14.6.2.1 [temp.dep.type]第8段,如果是,则类型依赖于(除其他外)

a simple-template-id in which either the template name is a template parameter or any of the template arguments is a dependent type or an expression that is type-dependent or value-dependent 一个simple-template-id ,其中模板名称是模板参数或任何模板参数是依赖类型或依赖于类型或依赖于值的表达式

This applies to alias template specializations, even if the resulting type does not depend on the template argument: 这适用于别名模板特化,即使结果类型不依赖于模板参数:

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

Is a change to the rules for cases like this warranted? 这样的案件的规则是否有必要改变?

And there's a note in that issue: 这个问题有一个注释:

Notes from the October, 2012 meeting: 2012年10月会议记录:

CWG agreed that no typename should be required in this case. CWG同意在这种情况下不需要任何typename In some ways, an alias template specialization is like the current instantiation and can be known at template definition time. 在某些方面,别名模板特化与当前实例化类似,可以在模板定义时知道。

The issue is still in "drafting" status, but it looks like the compiler vendors are already implementing the intended resolution. 该问题仍然处于“起草”状态,但看起来编译器供应商已经在实现预期的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM