In relation to this post, please explain this behavior:
#include <stdio.h>
struct B { B(B&) { } B() { } };
struct A {
template<typename T>
A(T&){ printf("A(T&)\n"); }
A() { }
// B b; // when this is uncommented, output changes
int i;
};
int main() {
A a;
A b(a);
// B b; commented:
// template wins:
// A<A>(A&) -- specialization
// A(A const&); -- implicit copy constructor
// (prefer less qualification)
// B b; uncommented:
// implicit copy constructor wins:
// A<A>(A&) -- specialization
// A(A&); -- implicit copy constructor
// (prefer non-template)
printf("\nA\n");
A const a1;
A b1(a1);
// B b; commented:
// implicit copy constructor wins:
// A(A const&) -- specialization
// A(A const&) -- implicit copy constructor
// (prefer non-template)
// B b; uncommented:
// template wins:
// A(A const&) -- specialization
// (implicit copy constructor not viable)
}
Output changes when B b; is uncommented.
Apparently, the implicit copy constructor changes from A(A const&) to A(A &) when B b; is uncommented. Why? When I change B(B&){} to B(const B&){} the copy constructor changes back to A(A const&). Now the compiler is satisfied that the formal parameter of A() will be const? Does this have anything to do with the standard? (I’m using gcc 4.2.4.)
The signature of the implicit copy constructor for class
AisA(const A&)only if feasible. When you uncomment theB b;line, this copy constructor is not viable because the copy constructor forBneeds a non-const input parameter.In this case, the implicit copy constructor is also the non-const version:
A(A&);.This is the reason way uncommenting
B b;in your class definition changes the implicit copy constructor and, consequently, changes your program behaviour.EDIT: Not directly related, but for completeness sake: if
Bhad no accessible copy constructor (because it is declaredprivateor deleted),Awould not have an implicit copy constructor.