gpt4 book ai didi

c++ - 当非限定名称查找涉及 using-directives 时 [basic.scope.hiding]p2 的解释

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:43:59 28 4
gpt4 key购买 nike

在c++中有两种隐藏的名字:

1) 普通名称隐藏:[basic.scope.hiding]p1 ( http://eel.is/c++draft/basic.scope.hiding#1 ):

A name can be hidden by an explicit declaration of that same name in a nested declarative region or derived class ([class.member.lookup]).

2)隐藏在[basic.scope.hiding]p2(http://eel.is/c++draft/basic.scope.hiding#2)中的特殊名称类型:

A class name ([class.name]) or enumeration name ([dcl.enum]) 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.

我很想知道在执行非限定名称查找时名称隐藏如何与 using 指令交互。

对于第一种名称,隐藏行为非常清楚。这是因为 [basic.scope.hiding]p1 已根据 [basic.lookup.unqual] ( http://eel.is/c++draft/basic.lookup.unqual ) 部分中的规则重新表述

对于第二种名称隐藏,还没有做同样的事情。那么现在出现以下问题:

*) 这第二种类型的名称隐藏应该如何与涉及使用指令的非限定名称查找交互?

我在标准的其他地方找到 [namespace.udir]p2 ( http://eel.is/c++draft/namespace.udir#2),我认为这是回答这个问题的关键:

A using-directive specifies that the names in the nominated namespace can be used in the scope in which the using-directive appears after the using-directive. During unqualified name lookup ([basic.lookup.unqual]), the names appear as if they were declared in the nearest enclosing namespace which contains both the using-directive and the nominated namespace. [ Note: In this context, “contains” means “contains directly or indirectly”. — end note ]

将此规则的 as if 部分应用于 [basic.scope.hiding]p1 与 [basic.lookup.unqual] 部分中的规则保持一致。此应用程序也符合 [basic.scope.hiding]p4 ( http://eel.is/c++draft/basic.scope.hiding#4 ) 所以这看起来很有希望。

因此,我认为我们可以通过类似地将 [namespace.udir]p2 的 as if 部分应用于 [basic.scope.hiding]p2 来回答问题 *)。此应用程序也与 [basic.scope.hiding]p4 一致。我认为这也是对c++标准最自然、最不复杂的解释。

然而,问题在于 Clang 和 GCC 的解释与我不同。例如:

namespace N { static int i = 1; }
namespace M { struct i {}; }
using namespace M;
using namespace N;
int main() { sizeof(i); }

根据我的解释,这个程序应该是良构的,i 应该作为整型变量来查找。 Clang 和 GCC 都不同意这一点,因为名称查找具有歧义。

在 Clang 的情况下,这种更复杂的解释会导致以下错误:

namespace N { static int i = 1; }
namespace M { struct i {}; }
namespace P {
using N::i;
using M::i;
}
namespace Q { using M::i; }
using namespace P;
using namespace Q;
int main() { sizeof (i); }

没有报错,但有变化

using namespace P;
using namespace Q;

进入

using namespace Q;
using namespace P;

我们得到名称查找歧义错误。 GCC 至少在这里是一致的。

我是否正确解释了 C++ 标准?

最佳答案

我认为这里的关键短语是:

A name can be hidden by an explicit declaration of that same name in a nested declarative region or derived class (10.2).

A class name (9.1) or enumeration name (7.2) can be hidden by the name of a variable, data member, function, or enumerator declared in the same scope.

在这个例子中:

namespace N { static int i = 1; }
namespace M { struct i {}; }
using namespace M;
using namespace N;
int main() { sizeof(i); }

两个 i 都在不同的非嵌套范围内声明,因此没有隐藏。名称查找找到它们时,就好像它们是在 :: 中声明的,但这不是隐藏规则所规定的。

否则,我们有,来自 [basic.lookup]:

Name lookup shall find an unambiguous declaration for the name (see 10.2). Name lookup may associate more than one declaration with a name if it finds the name to be a function name;

:: 中没有明确的声明,所以这段代码格式错误,错误正确。另一个示例也是如此,因此存在一些 using-declaration clang 编译它的顺序的事实是一个错误。

虽然这是非规范的,但 [namespace.udir] 中有一个示例可以清楚地说明这种解释:

[ Note: In particular, the name of a variable, function or enumerator does not hide the name of a class or enumeration declared in a different namespace. For example,

namespace A {
class X { };
extern "C" int g();
extern "C++" int h();
}

namespace B {
void X(int);
extern "C" int g();
extern "C++" int h(int);
}

using namespace A;
using namespace B;
void f() {
X(1); // error: name X found in two namespaces
g(); // OK: name g refers to the same entity
h(); // OK: overload resolution selects A::h
}

—end note ]

关于c++ - 当非限定名称查找涉及 using-directives 时 [basic.scope.hiding]p2 的解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31702956/

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