gpt4 book ai didi

c++ - 继承构造函数后查找基类名

转载 作者:行者123 更新时间:2023-11-30 01:45:26 25 4
gpt4 key购买 nike

考虑以下代码:

struct base {};

struct derived : public base {
using base::base;
base foo() const; // how does name lookup on 'base' here work?
};

从直觉上看,这段代码显然是有效的,并且确实可以编译(使用 gcc 和 clang 进行了测试)。

但是,我想了解标准中的哪些内容使其有效。具体来说,我想了解 base foo()base 的名称查找如何找到基类类型而不是继承的构造函数。

这是我对标准措辞的分析,表明它应该解析为构造函数。这可能是错误的,但我想了解我哪里出错了。

我从 [class.member.lookup] p1 开始:

Member name lookup determines the meaning of a name (id-expression) in a class scope. [...] For an id-expression, name lookup begins in the class scope of this

p7 告诉我们名称查找的结果是什么:

The result of name lookup for [a member name] f in [a class scope] C is the declaration set of S(f, C)

我正在尝试遵循此过程,Cderived,而 f 是使用 basebase foo() 中。

“声明集”在p3中定义:

The lookup set for f in C, called S(f, C), consists of two component sets: the declaration set, a set of members named f; [...]

p4 告诉我们什么进入了声明集:

If C contains a declaration of the name f, the declaration set contains every declaration of f declared in C that satisfies the requirements of the language construct in which the lookup occurs.

using base::base 是名称base (f) 在derived (C)。该段落继续举例说明声明 not 满足发生查找的语言构造的要求的含义,但没有任何内容可以排除 using base::来自此查找的基础

接下来,在 p3 中,我们被告知如何处理声明集中的 using-declarations:

In the declaration set, using-declarations are replaced by the set of designated members that are not hidden or overridden by members of the derived class

那么using base::base 指定了哪些成员呢?在我看来,[class.qual] p2 回答了这个问题:

In a lookup in which function names are not ignored and the nested-name-specifier nominates a class C:

  • if the name specified after the nested-name-specifier, when looked up in C, is the injected-class-name of C, or

  • in a using-declaration that is a member-declaration, if the name specified after the nested-name-specifier is the same as identifier [...] in the last component of the nested-name-specifier

the name is instead considered to name the constructor of class C.

有一个脚注阐明了“不忽略函数名称的查找”的含义:

Lookups in which function names are ignored include names appearing in a nested-name-specifier, an elaborated-type-specifier, or a base-specifier.

这些都不是所讨论的名称查找的情况,所以在我看来这一段适用,并且说 using base::base 指定构造函数(这也是你鉴于它是继承的构造函数声明,我会凭直觉期待)。

在派生类范围内找到声明(指定基类构造函数)后,我们继续遵循 [class.member.lookup] p4:

If the resulting declaration set is not empty, the subobject set contains C itself, and calculation is complete.

也就是说,由于名称查找在派生类范围内找到结果,因此它不会继续在基类范围内查找(它会在哪里找到 injected-class-name 基地)。 [顺便说一句,即使名称查找继续进入基类范围,我也看不到任何可以消除构造函数和注入(inject)类名称之间歧义的内容]。

我的推理哪里出了问题?

最佳答案

该标准煞费苦心地指出构造函数没有名称。无法通过名称查找找到它,因为它没有名称。

C++11 §12.1/1

Constructors do not have names.

C+11 §12.1/2

Because constructors do not have names, they are never found during name lookup.

关于c++ - 继承构造函数后查找基类名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34671852/

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