【问题标题】:Trying to understand [class.qual]/2 in the C++ Standard试图理解 C++ 标准中的 [class.qual]/2
【发布时间】:2016-02-25 12:51:22
【问题描述】:

根据我获得的here 的答案,尽管clangvs2015 接受了它,但下面的代码格式不正确。

#include <iostream>
class A {
public:
    A() { std::cout << "A()" << '\n'; }
};

int main()
{
  A::A();
}

尽管如此,下面的代码似乎在所有 3 个编译器中都有效(请参阅 live example)。 AFAICT,根据 [class.qual/2] 代码格式错误。还是我在这里遗漏了什么?

#include <iostream>
struct B { B() { std::cout << "B()" << '\n'; } };
struct A : public B { };
int main()
{
    A::B();
}

另外,根据 [class.qual]/2,下面的代码格式正确,在这种情况下,所有 3 个编译器都会产生预期的输出(参见示例 here)。

include <iostream>
struct B { B() { std::cout << "B()" << '\n'; } };
struct A : public B { using B::B; A() { std::cout << "A()" << '\n'; }  void f() { B(); } };
int main()
{
    A a;
    a.f();
}

输出:

B()
A()
B()

但我想知道 using-declaration 命名构造函数有什么用处,就像上面 A 类中的 (using B::B;) 一样。请注意,这个 using-declaration 在这种情况下是完全不相关的,无论 B 是否是 A 的基类。

【问题讨论】:

    标签: c++ constructor language-lawyer c++14


    【解决方案1】:

    我认为您的第二个样本格式正确。 [class.qual]/2 中的规则指出,如果在 C 中查找时在 nested-name-specifier 之后指定的名称是 C 的注入类名称,则该名称引用构造函数.在A::B 的情况下,在嵌套名称说明符之后指定的名称是B 的注入类名称(由于继承而可见),而不是A。在这种情况下,A::B 明确地命名了一个类型,A::B() 创建了一个临时的 B 实例。

    使用声明命名构造函数对于提升带参数的基类构造函数很有用:

    struct B { B(int a) { std::cout << "B " << a << '\n'; } };
    struct A : public B { using B::B; };
    int main()
    {
        A a{1}; //would not be valid without the using-declaration
    }
    

    【讨论】:

    • 你上面的例子似乎证实了你所说的。但是您能否提供支持这种结构的标准报价。我以前从未见过这种结构。
    • 标准语言在我的问题中有点长,但你可能想看看[class.inhctor]
    • 在快速浏览 [class.inhctor] 之后,我不得不同意你的看法。它似乎回答了我的第二个问题(+1)。但我仍然不相信我的第一个问题。
    • 在 [class.qual]/2 的示例中,关于我的第一个问题,声明 B::A ba; // object of type A 似乎与您在上面所说的相矛盾。
    • @Belloc 它有什么矛盾? B::A(); 声明一个函数,B::A ba; 创建一个名为 ba 的自动变量,类型为 A
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-11
    • 2016-10-15
    • 2013-10-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多