"typename"何时可以与明确引用类型的标识符一起使用? [英] When can `typename` be used with identifiers that unambiguously refer to a type?
问题描述
通常,typename
用于在标识符可能指向类型或其他类型的情况之间进行歧义消除:
Normally, typename
is used to disambiguate between cases where an identifier may refer to a type, or may refer to something else:
template<class T>
void foo(typename T::type value) {
// ...
}
当标识符已经是类型时,什么时候可以使用typename
?
1..如果已经有一个使用此名称的课程,可以使用它吗?
When can typename
be used when an identifier is already a type?
1. Can it be used if there's already a class with this name?
class MyClass{};
void foo(typename MyClass value) {}
2..它可以与声明为类型的模板参数一起使用吗?
2. Can it be used with a template parameter that's declared as a type?
template<class T>
void foo(typename T value) {}
3.可以与明确类型的内部类一起使用吗?
3. Can it be used with inner classes that are unambiguously types?
class A {
public:
class B {};
};
// Compiles; no typename necessary
void foo(A::B value) {}
// This compiles too on gcc and msvc
void bar(typename A::B value) {}
编译器解释
情况1: MSVC认为这可以; gcc和clang抛出错误
Compiler interpretation
Case 1: MSVC considers this OK; gcc and clang throw an error
情况2: MSVC认为这样做可以; gcc和clang抛出错误
Case 2: MSVC considers this OK; gcc and clang throw an error
情况3: A::B
无疑是一种类型,但是gcc和clang现在允许使用typename
.
Case 3: A::B
is unambiguously a type, but gcc and clang now permit the use of typename
.
推荐答案
关键字typename
仅由C ++允许语法以引入模板类型参数或在限定名称前,即包含::
令牌的内容.
The keyword typename
is only permitted by the C++ syntax to introduce a template type parameter, or before a qualified name, i.e. something containing the ::
token.
因此,您的#1和#2格式错误,因为MyClass
和T
是不合格的名称,不包含任何::
.
So your #1 and #2 are ill-formed because MyClass
and T
are unqualified names, not containing any ::
.
在限定名称之前,typename
令牌为:
Before a qualified name, the typename
token is:
- 基类之前的语法不允许类定义开头的名称,或从属并且是未知专业化的成员
- 否则是可选的,无论是否在模板声明中
- not allowed by the grammar before a base class name in the head of a class definition, or in combination with the
class
,struct
, orunion
keywords; a qualified name is always treated as a type in these contexts - otherwise required, if the qualified name is dependent and a member of an unknown specialization
- otherwise optional, whether within a template declaration or not
C ++ 17 [temp.res]/3,5,6:
C++17 [temp.res]/3,5,6:
当 qualified-id 旨在引用不是当前实例成员的类型,而其 nested-name-specifier 引用从属类型时,它必须以关键字
typename
为前缀,形成一个 typename-specifier . ...
When a qualified-id is intended to refer to a type that is not a member of the current instantiation and its nested-name-specifier refers to a dependent type, it shall be prefixed by the keyword
typename
, forming a typename-specifier. ...
用作 class-or-decltype (条款[class.derived])或 elaborated-type-specifier 的名称的合格名称被隐式假定为为类型命名,而不使用typename
关键字.在嵌套名称说明符中,它立即包含依赖于模板参数的嵌套名称说明符,其中 identifier 或假定使用simple-template-id 命名类型,而不使用typename
关键字. [注意:这些构造的语法不允许使用typename
关键字. -尾注]
A qualified name used as the name in a class-or-decltype (Clause [class.derived]) or an elaborated-type-specifier is implicitly assumed to name a type, without the use of the typename
keyword. In a nested-name-specifier that immediately contains a nested-name-specifier that depends on a template parameter, the identifier or simple-template-id is implicitly assumed to name a type, without the use of the typename
keyword. [Note: The typename
keyword is not permitted by the syntax of these constructs. - end note]
如果对于给定的一组模板参数,实例化的模板专门化是指表示类型或类模板的 qualified-id ,而 qualified- id 指的是未知专业的成员, qualified-id 应该以typename
为前缀,或在其隐式命名上述类型的上下文中使用
If, for a given set of template arguments, a specialization of a template is instantiated that refers to a qualified-id that denotes a type or a class template, and the qualified-id refers to a member of an unknown specialization, the qualified-id shall either be prefixed by typename
or shall be used in a context in which it implicitly names a type as described above.
#3格式正确,即使名称不依赖模板参数,也不在模板声明中.
So your #3 is well-formed, even though the name does not depend on a template parameter and isn't even in a template declaration.
请注意,C ++ 20将添加更多上下文,其中typename
即使是从属名称,也是可选的,因为可以从上下文中明确确定名称只能表示类型.
Note C++20 will add many more contexts where typename
is optional even with a dependent name, because it's possible to unambiguously determine from the contexts that the name can only mean a type.
这篇关于"typename"何时可以与明确引用类型的标识符一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!