【问题标题】:Lookup of base class name after inheriting constructor继承构造函数后查找基类名称
【发布时间】:2016-04-12 19:54:13
【问题描述】:

考虑以下代码:

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开始:

成员名称查找确定名称(id-expression)在类范围内的含义。 [...] 对于 id-expression,名称查找从 this 的类范围开始

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

[a member name] f in [a class scope] C 的名称查找结果是S(f, C)的声明集

我正在尝试遵循此程序,Cderivedf 是在 base foo() 中使用 base

“声明集”定义在p3:

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

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

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

using base::basederived (C) 中名称 base (f) 的声明。该段落继续举例说明声明 not 满足查找发生的语言结构的要求意味着什么,但没有任何内容可以将 using base::base 排除在此查找之外。

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

在声明集中,using-declarations被派生类的成员不隐藏或覆盖的指定成员集替换

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

在不忽略函数名的查找中, nested-name-specifier 指定一个类 C:

  • 如果在 nested-name-specifier 之后指定的名称,当在 C 中查找时,是 C 的注入类名称,或者

  • using-declaration 中,它是一个 member-declaration,如果在 nested-name-specifier 之后指定的名称是相同的 identifier [...] 在 nested-name-specifier

  • 的最后一个组件中

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

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

忽略函数名称的查找包括出现在 nested-name-specifierelaborated-type-specifierbase-specifier 中的名称.

这些都不是问题名称查找的情况,所以在我看来,这一段适用,并说using base::base 指定构造函数(这也是你直观地期望的,因为它是继承构造函数声明)。

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

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

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

我的推理哪里出错了?

【问题讨论】:

    标签: c++ c++11 name-lookup inheriting-constructors injected-class-name


    【解决方案1】:

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

    C++11 §12.1/1

    构造函数没有名字。

    C+11 §12.1/2

    因为构造函数没有名字,所以它们是 在名称查找期间从未找到。

    【讨论】:

    • [class.qual] p2 中的那句话是什么意思?
    • @HighCommander4:大概是关于使用功能符号转换来调用构造函数。
    • 但是什么排除了该段落适用于using base::base
    • 抱歉,我现在查看了该段落,它继续说:“这样的构造函数名称只能用于命名构造函数的声明的 declarator-id 或 using-宣言”。该段落中还有一条注释,说“注意:例如,构造函数在详细类型说明符中不是可接受的查找结果,因此不会使用构造函数代替注入的类名。-结束笔记”。您在哪里阅读不包含该文本的内容?
    • 嗯,using base::base 是一个使用声明。
    猜你喜欢
    • 2017-11-17
    • 2013-10-24
    • 1970-01-01
    • 2018-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多