Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to understand [class.qual]/2 in the C++ Standard

According to the answers I obtained here, the code below is ill-formed, notwithstanding the fact that clang and vs2015 accept it.

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

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

Nevertheless the code below appears to work in all 3 compilers (see live example). AFAICT, according to [class.qual/2] the code is ill-formed. Or am I missing something here?

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

Also, according to [class.qual]/2, the code below is well-formed and in this case, all 3 compilers produce the expected output (see example 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();
}

Output:

B()
A()
B()

But I'd like to know what is the usefulness of a using-declaration naming a constructor, as the one (using B::B;) in class A above. Note that this using-declaration is totally irrelevant in this case, no matter whether B is a base class of A, or not.

like image 407
Belloc Avatar asked Oct 18 '22 21:10

Belloc


1 Answers

I think that the your second sample is well-formed. The rule in [class.qual]/2 states that the name refers to the constructor if the name specified after the nested-name-specifier when looked up in C is the injected-class-name of C. In the case of A::B, the name specified after the nested-name-specifier is the injected-class-name of B (visible due to inheritance), not A. In this case, A::B unambiguously names a type, A::B() creates a temporary B instance.

Using-declarations naming constructors can be useful to promote base-class constructors which take arguments:

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
}
like image 153
TartanLlama Avatar answered Oct 27 '22 10:10

TartanLlama