template<class T>
T::type<int> f(){
}
根据[temp.names#3.4],
如果在不是转换函数ID的名称后面跟着“<”,则将其解释为模板参数列表的定界符,并且
- 在using-declarator中是终端名称([namespace.udecl]), - 在declarator-id中是终端名称([dcl.meaning]),或 - 在除嵌套名称说明符之外的仅类型上下文中是终端名称([temp.res])。
根据[temp.res#general-4.3.1],由于以下规则,“T :: type ”确实满足上述规则(强调我的):
如果限定或未限定名称是以下内容的终端名称,则称其处于“仅类型上下文”中:
- 在命名空间作用域中简单声明或函数定义的decl-specifier-seq的decl-specifier中, - 在类定义的成员说明符中, - 在模板头中, - 在基类说明符中, - 在成员初始化列表中, - 在catch子句中, - 在新表达式的类型-id中, - 在typeid表达式的类型-id中, - 在静态断言中的常量表达式中。
T::type<int>
是模板函数f
的函数定义的声明符号,该函数在命名空间范围内,因此终端名称type
被称为仅类型上下文。
此外,根据[temp.res#general-5]
终端名称为依赖项且位于仅类型上下文中的限定符ID被认为表示类型。
因此,由于[temp.res#general-5],限定符ID T::type<int>
被认为表示类型,而<
符号被解释为模板参数列表的分隔符,由于[temp.names#3.4]。因此,这个例子应该是合法的。然而,它已被Clang和GCC拒绝。
我想知道,未来的实现是否不需要在这个例子中使用关键字typename
和template
?
template
来表示type
是一个模板名称,因为根据[temp.names#3.4],它已经被明确指定为模板名称。 - xmh0511f
是实际的函数模板。 - Daif
被声明为函数模板,然而,[temp.res#general-4.3.1] 只涉及 语法,它并没有提到函数定义的声明说明符。 - xmh0511template
和typename
关键字?可能对其中一些内容有所启发。 - WhozCraig