gpt4 book ai didi

c++ - 在 C++ 中声明具有相同名称的类型和模板

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:09:11 25 4
gpt4 key购买 nike

这是一个学术问题。

GCC bug 38764 的报告中,有如下例子:

template < class T > struct A {};
typedef A< float > A; // Accepted by Comeau, but not GCC
typedef ::A< float > A; // Accepted by GCC but not Comeau

我知道为什么代码可能无效,但我对其中一条评论有疑问:

This code is invalid but the standard says for this case no diagnostic is required so both compilers are correct according to the standard.

为什么“无效”的代码被标准接受为有效的?对于这种情况(模板 + 具有相同名称的类型),以及一般情况下,对于各种实体(类型、模板、函数、变量)的 namespace ,标准有何规定?

最佳答案

当标准说“不需要诊断”时,这意味着编译器不必产生有关无效代码的错误或警告,但根据标准,代码的行为仍未定义,因此它不会必然有可预见的结果。这是为了让编译器编写者的工作更轻松,这样他们就不必检测相对罕见或特别难以检测的程序员错误。

但是,当违反“不需要诊断”的规则时,编译器不会禁止检测无效代码并出于对用户的礼貌而产生错误。因此,在给出的示例中,gcc 正在为一种特定类型的无效代码生成礼貌诊断,而 Comeau 正在为类似类型的无效代码生成礼貌诊断。但是这两种诊断都不是必需的,因此在任何情况下,其他编译器都不会因为不产生错误消息而违反标准。在任何情况下,代码的行为都未定义。

关于类名和模板名的几个相关标准引用:

3.4/1

The name lookup rules apply uniformly to all names (including typedef-names (7.1.3), namespace-names (7.3) and class-names (9.1)) wherever the grammar allows such names in the context discussed by a particular rule. Name lookup associates the use of a name with a declaration (3.1) of that name. Name lookup shall find an unambiguous declaration for the name (see 10.2). [...]

7.1.3/3

In a given scope, a typedef specifier shall not be used to redefine the name of any type declared in that scope to refer to a different type. [Example:

class complex { /* ... */ }; 
typedef int complex; // error: redefinition

—end example] Similarly, in a given scope, a class or enumeration shall not be declared with the same name as a typedef-name that is declared in that scope and refers to a type other than the class or enumeration itself. [...]

9.1/2

A class definition introduces the class name into the scope where it is defined and hides any class, object, function, or other declaration of that name in an enclosing scope (3.3). If a class name is declared in a scope where an object, function, or enumerator of the same name is also declared, then when both declarations are in scope, the class can be referred to only using an elaborated-type-specifier (3.4.4).

14/5

A class template shall not have the same name as any other template, class, function, object, enumeration, enumerator, namespace, or type in the same scope (3.3), except as specified in (14.5.4). Except that a function template can be overloaded either by (non-template) functions with the same name or by other function templates with the same name (14.8.3), a template name declared in namespace scope or in class scope shall be unique in that scope.

14.5.4/1

A primary class template declaration is one in which the class template name is an identifier. A template declaration in which the class template name is a template-id, is a partial specialization of the class template named in the template-id. A partial specialization of a class template provides an alternative definition of the template that is used instead of the primary definition when the arguments in a specialization match those given in the partial specialization (14.5.4.1). [...]

所以,总结一下:

  • typedef不能改变现有类型的含义
  • class 名称可以与某些类型的名称冲突,但不会与其他类名称冲突
  • template 类名不包含模板参数,不能和任何东西冲突,即使是普通类名允许冲突的东西
  • 模板特化被认为与其相应的通用模板具有相同的template-id(名称),但它们(显然)不是同一类型。

所以这里在两个方向上都存在冲突。 template 名称不允许与任何内容冲突,并且 typedef 不允许将 A 从模板类类型更改为模板类类型。

关于c++ - 在 C++ 中声明具有相同名称的类型和模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3368129/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com