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

Bel*_*loc 5 c++ constructor language-lawyer c++14

根据我在这里得到的答案,下面的代码是不正确的,尽管事实clangvs2015接受它.

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

int main()
{
  A::A();
}
Run Code Online (Sandbox Code Playgroud)

然而,下面的代码似乎适用于所有3个编译器(参见实例).AFAICT,根据[class.qual/2],代码格式不正确.或者我在这里遗漏了什么?

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

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

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();
}
Run Code Online (Sandbox Code Playgroud)

输出:

B()
A()
B()
Run Code Online (Sandbox Code Playgroud)

但是我想知道命名构造函数的using声明的用处是什么,如上面的using B::B;class ()A.请注意,这种using声明在这种情况下完全无关紧要,无论是否B是基类A.

Tar*_*ama 3

我认为你的第二个样本格式良好。中的规则指出,如果在查找时嵌套[class.qual]/2名称说明符后面指定的名称是 的注入类名称,则该名称引用构造函数。在 的情况下,nested-name-specifier 之后指定的名称是 的注入类名称(由于继承而可见),而不是。在这种情况下,明确命名类型,创建临时实例。CCA::BBAA::BA::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
}
Run Code Online (Sandbox Code Playgroud)