"typename"何时可以与明确引用类型的标识符一起使用? [英] When can `typename` be used with identifiers that unambiguously refer to a type?

查看:134
本文介绍了"typename"何时可以与明确引用类型的标识符一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通常,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格式错误,因为MyClassT是不合格的名称,不包含任何::.

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, or union 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆