c++ - 试图理解 C++ 标准中的 [class.qual]/2

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

根据我得到的答案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 命名构造函数有什么用处,例如类中的构造函数(using B::B;) A 以上。请注意,此 using-declaration 在这种情况下完全不相关,无论 B 是否是 A 的基类。

最佳答案

我认为您的第二个样本格式正确。 [class.qual]/2 中的规则指出,如果在 中查找时在 nested-name-specifier 之后指定的名称,则该名称指的是构造函数CC 的注入(inject)类名。在 A::B 的情况下,在 nested-name-specifier 之后指定的名称是 B 的注入(inject)类名(由于继承可见),而不是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
}

关于c++ - 试图理解 C++ 标准中的 [class.qual]/2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33870642/

相关文章:

c++ - 解析来自简单 POST 请求的异常

c++ - Visual Studio 中的 OpenCV 构建错误

c# - 构造函数继承

c++ - 何时在空实例上调用成员函数会导致未定义的行为?

c - 为什么C语言允许用户创建与已有库函数同名的宏?

c++ - 如何在引用超出范围后检测ptr是否仍在引用有效引用

c++ - 如何在不使用循环的情况下进行排序

java - 如何在 Apache Tomcat 启动时创建单例

Javascript `new` 运算符和原型(prototype)

c - 未定义或未指定的行为?