[basic.scope.hiding] 中的 "same scope" 在 C++ 标准中的确切含义是什么?
What the C++ standard exactly means by "same scope" in [basic.scope.hiding]?
在 C++14 标准中,[basic.scope.hiding] 第 2 段 (3.3.10.2) 说:
A class name or enumeration name can be hidden by the name of a variable, data member,
function, or enumerator declared in the same scope. If a class or enumeration name and a variable, data member, function, or enumerator are declared in the same scope (in any order) with the same name, the class or enumeration name is hidden wherever the variable, data member, function, or enumerator name is visible.
我对“相同范围”的措辞感到不安。事实上,在下面的代码片段中,class C
和变量 C
在同一范围内声明的情况是什么?
namespace case_1 {
int C;
class C;
// Here C refers to variable
}
namespace case_2 {
class C;
namespace nested {
int C;
// Here C refers to variable
}
}
namespace case_3 {
int C;
namespace nested {
class C;
// Here C refers to class
}
}
namespace case_4 {
enum Enum { A, B, C };
class C;
// Here C refers to enumerator
}
假设 1:“相同范围”意味着“相同块”
如果我们坚持这个假设,案例1应该受到规则3.3.10.2的关注。案例2呢?我猜它包含在规则 3.3.10.1 中:
A name can be hidden by an explicit declaration of that same name in a nested declarative region or derived class.
此外,这个假设很好地解释了案例 3,其中 class 名称隐藏了变量名称(而不是相反)但无法解释案例 4。实际上,C
枚举器是在与 C
class 不同的块中声明,但 class 仍然隐藏。
假设 2:“在相同范围内声明”意味着“具有完全相同的范围”
如果该假设为真,则我的代码中描述的所有情况都不会受到该规则的影响,因为两个名称不可能具有完全相同的范围。即使 case_1
中的变量也具有与 class 不同的作用域。事实上,变量名的范围在它的声明之后开始,所以在 class 名称之前。
假设 3:“在同一范围内声明”意味着“其中一个名称在另一个名称的范围内声明”
如果这个假设成立,那么上述所有情况都应该属于规则3.3.10.2。事实上,在case_1
和case_3
中,C
class是在C
变量的范围内声明的;在case_2
中,C
变量声明在C
class的范围内;并且,在 case_4
中,C
class 在 C
枚举器的范围内声明。但是,case_3
不遵循规则,因为它是应该“获胜”并保持可见的变量。
如您所见,我的每一个假设都有一个缺点,我真的不明白标准在该段中所说的“相同范围”的确切含义。
在这里,范围是指可见性。
两个名称在同一范围内当且仅当它们在某个地方同时已知(因此如果它们相同则变为 ambiguous/conflicting)。
"known" 我的意思是您可以 直接 访问它们(如果名称相同,则使用完全相同的语法)。
Indeed, C enumerator is declared in a different block than C class but the class is still hidden.
这是错误的。
实际上 enum
并没有将其成员封装在本地范围内。换句话说,enum
成员与 enum
本身在同一范围内。
例如,如果我声明
enum MY_ENUM {A, B};
我可以通过 My_ENUM::A
和 My_ENUM::B
或仅通过 A
和 B
访问这些值。此外,允许隐式转换为 int
。
如果你想将值封装在 MY_ENUM
的本地范围内(因此禁止 A
和 B
的访问),你必须声明 enum
改为 enum class
。
enum class MY_ENUM {A, B};
但是,将不再允许隐式转换为 int
。
what are the cases where the class C and the variable C are declared in the same scope?
案例1和案例4是同一个范围。案例2和案例3不是同一个范围
在这种情况下,我确实无法在标准中找到 "same" 的准确定义,但有意义且与您的测试结果相匹配的解释是比较 最小的封闭每个声明的范围(或者更确切地说,声明区域1)。
Hypothesis 1: "same scope" means "same block"
虽然块有作用域,但它们并不等同。例如还有命名空间范围和 class 范围。
but can't explain the case 4. Indeed, C enumerator is declared in a different block than C class but the class is still hided.
枚举声明没有作用域。枚举器和 class 在同一范围内。
Hypothesis 2: "declared in the same scope" means "have exactly the same scope"
正如您所说,没有声明可以与另一个声明具有完全相同的范围,因此这种解释会使规则变得毫无意义。
Hypothesis 3: "declared in the same scope" means "one of the name is declared inside the scope of the other"
这是不正确的解释,因为嵌套范围可以在一个声明的范围内,但就所讨论的规则而言,它不是同一范围。
1 在最新的标准草案中,措辞已更改为使用术语 "declarative region",这显然与 "scope" 具有微妙的不同含义。不过,它不会改变规则的预期含义。
在 C++14 标准中,[basic.scope.hiding] 第 2 段 (3.3.10.2) 说:
A class name or enumeration name can be hidden by the name of a variable, data member, function, or enumerator declared in the same scope. If a class or enumeration name and a variable, data member, function, or enumerator are declared in the same scope (in any order) with the same name, the class or enumeration name is hidden wherever the variable, data member, function, or enumerator name is visible.
我对“相同范围”的措辞感到不安。事实上,在下面的代码片段中,class C
和变量 C
在同一范围内声明的情况是什么?
namespace case_1 {
int C;
class C;
// Here C refers to variable
}
namespace case_2 {
class C;
namespace nested {
int C;
// Here C refers to variable
}
}
namespace case_3 {
int C;
namespace nested {
class C;
// Here C refers to class
}
}
namespace case_4 {
enum Enum { A, B, C };
class C;
// Here C refers to enumerator
}
假设 1:“相同范围”意味着“相同块”
如果我们坚持这个假设,案例1应该受到规则3.3.10.2的关注。案例2呢?我猜它包含在规则 3.3.10.1 中:
A name can be hidden by an explicit declaration of that same name in a nested declarative region or derived class.
此外,这个假设很好地解释了案例 3,其中 class 名称隐藏了变量名称(而不是相反)但无法解释案例 4。实际上,C
枚举器是在与 C
class 不同的块中声明,但 class 仍然隐藏。
假设 2:“在相同范围内声明”意味着“具有完全相同的范围”
如果该假设为真,则我的代码中描述的所有情况都不会受到该规则的影响,因为两个名称不可能具有完全相同的范围。即使 case_1
中的变量也具有与 class 不同的作用域。事实上,变量名的范围在它的声明之后开始,所以在 class 名称之前。
假设 3:“在同一范围内声明”意味着“其中一个名称在另一个名称的范围内声明”
如果这个假设成立,那么上述所有情况都应该属于规则3.3.10.2。事实上,在case_1
和case_3
中,C
class是在C
变量的范围内声明的;在case_2
中,C
变量声明在C
class的范围内;并且,在 case_4
中,C
class 在 C
枚举器的范围内声明。但是,case_3
不遵循规则,因为它是应该“获胜”并保持可见的变量。
如您所见,我的每一个假设都有一个缺点,我真的不明白标准在该段中所说的“相同范围”的确切含义。
在这里,范围是指可见性。
两个名称在同一范围内当且仅当它们在某个地方同时已知(因此如果它们相同则变为 ambiguous/conflicting)。
"known" 我的意思是您可以 直接 访问它们(如果名称相同,则使用完全相同的语法)。
Indeed, C enumerator is declared in a different block than C class but the class is still hidden.
这是错误的。
实际上 enum
并没有将其成员封装在本地范围内。换句话说,enum
成员与 enum
本身在同一范围内。
例如,如果我声明
enum MY_ENUM {A, B};
我可以通过 My_ENUM::A
和 My_ENUM::B
或仅通过 A
和 B
访问这些值。此外,允许隐式转换为 int
。
如果你想将值封装在 MY_ENUM
的本地范围内(因此禁止 A
和 B
的访问),你必须声明 enum
改为 enum class
。
enum class MY_ENUM {A, B};
但是,将不再允许隐式转换为 int
。
what are the cases where the class C and the variable C are declared in the same scope?
案例1和案例4是同一个范围。案例2和案例3不是同一个范围
在这种情况下,我确实无法在标准中找到 "same" 的准确定义,但有意义且与您的测试结果相匹配的解释是比较 最小的封闭每个声明的范围(或者更确切地说,声明区域1)。
Hypothesis 1: "same scope" means "same block"
虽然块有作用域,但它们并不等同。例如还有命名空间范围和 class 范围。
but can't explain the case 4. Indeed, C enumerator is declared in a different block than C class but the class is still hided.
枚举声明没有作用域。枚举器和 class 在同一范围内。
Hypothesis 2: "declared in the same scope" means "have exactly the same scope"
正如您所说,没有声明可以与另一个声明具有完全相同的范围,因此这种解释会使规则变得毫无意义。
Hypothesis 3: "declared in the same scope" means "one of the name is declared inside the scope of the other"
这是不正确的解释,因为嵌套范围可以在一个声明的范围内,但就所讨论的规则而言,它不是同一范围。
1 在最新的标准草案中,措辞已更改为使用术语 "declarative region",这显然与 "scope" 具有微妙的不同含义。不过,它不会改变规则的预期含义。