繁体   English   中英

继承构造函数后查找基类名称

[英]Lookup of base class name after inheriting constructor

考虑以下代码:

struct base {};

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

凭直觉,很明显,这段代码是有效的,并且确实可以编译(用gcc和clang测试)。

但是,我想了解标准中的哪些内容使其有效。 具体而言,我想了解名称查找如何basebase foo()发现的基类,而不是继承的构造。

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

我从[class.member.lookup] p1

成员名称查找确定类作用域中名称( id-expression )的含义。 [...]用于ID表达 ,名称查找开始于的类范围this

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

在[类范围] C对[成员名称] f进行名称查找的结果是S(f,C)的声明集

我正在尝试遵循此过程, derived Cf是在base foo()使用base

p3定义了“声明集”:

C f查找集称为S(f,C)包含两个组件集: 声明集 ,一组名为f的成员; [...]

p4告诉我们声明集的内容:

如果C包含名称为f的声明,则声明集包含C中声明的f每个声明,该声明满足查找所使用的语言构造的要求。

using base::basederivedC )中名称basef )的声明。 该段继续给的是什么意思的声明没有满足在其中查找出现的语言结构的要求的例子,但什么也没有说将排除using base::base从这个查找。

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

在声明集中, using-declaration由未被派生类的成员隐藏或覆盖的一组指定成员替换。

那么using base::base指定的成员是什么? 在我看来,这是[class.qual] p2的回答:

在不忽略函数名称且嵌套名称说明符提名类C的查找中:

  • 如果在Cnested-name- specifier之后指定的名称是C的注入类名称,则为

  • 使用声明这是一个成员声明 ,如果嵌套名说明符之后指定的名称是一样的,在嵌套名称说明符的最后一个组件标识符 [...]

该名称被认为是为类C的构造函数命名。

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

函数名称被忽略的查找包括出现在嵌套名称说明符详细类型说明符基本说明符中的名称

这些都不是问题名称查找的情况,因此在我看来,本段适用,并说using base::base指定了构造函数(由于继承是继承的,因此这也是直观的期望)构造函数声明)。

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

如果结果声明集不为空,则子对象集包含C本身,并且计算完成。

也就是说,由于名称查找在派生类范围中找到了结果,因此它不会继续在基类范围中查找(它将在其中找到注入的类名 base )。 [顺便说一句,即使名称查找继续进入基类范围,我也看不到任何会在构造函数和注入的类名之间产生歧义的东西]。

我的推理错在哪里?

该标准不遗余力地指出, 构造函数没有名称 无法通过名称查找找到它,因为它没有名称。

C ++ 11§12.1/ 1

构造函数没有名字。

C + 11§12.1/ 2

由于构造函数没有名称,因此在名称查找期间永远不会找到它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM