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

According to the answers I got here , the code below is poorly formed, despite the fact that clang and vs2015 accept it.

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

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

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

Furthermore, according to [class.qual] / 2, the code below is well-formed, in which case all 3 compilers produce the expected result (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; af(); } 

Output:

 B() A() B() 

But I would like to know what is the use of using a declaration calling the constructor as one ( using B::B; ) in class A above. Note that this use-declaration is completely irrelevant in this case, whether B base class of A or not.

+5
source share
1 answer

I think your second pattern is well formed. The rule in [class.qual]/2 states that the name refers to the constructor if the name specified after the nested qualifier when searching in C is the injected name of C In the case of A::B name given after the nested qualifier name is the entered class name B (visible due to inheritance), and not A In this case, A::B explicitly names the type, A::B() creates a temporary instance of B

Naming constructors using-declarations can be useful for promoting base class constructors that 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 } 
+3
source

Source: https://habr.com/ru/post/1236610/


All Articles