I've got this short snippet of code that I'd like to get a bit more information about as to why overload resolution is picking one constructor over another. Here's the code in question:
#include <iostream>
struct Base
{
};
struct Other
{
Other(const Other&)
{
std::cout << "Copy Constructor\n";
}
Other(const Base&)
{
std::cout << "Custom Constructor\n";
}
};
struct Derived : public Base, public Other
{
Derived() :
Other(*this)
{
}
};
int main()
{
Derived derived; // Prints "Copy Constructor"
system("pause");
return 0;
}
I'm assuming there's a section in the C++ Standard that defines the copy constructor as a better match than user defined constructors*? My assumption otherwise was that if no rule favoring the copy constructor existed, then the compiler would either go by the order of inheritance (as with the order of construction with multiple inheritance) or just give me an ambiguous constructor call error. However, reversing the order in which Derived
inherits from Base
and Other
doesn't change the output, which leads me to believe that my initial guess about copy constructors being favored is correct. Could anyone point me to the rule that determines the behavior I'm seeing?
* I checked cppreference.com's Overload Resolution page, but I didn't see any rule listed there that would explain the behavior I'm seeing (though I'm not completely fluent in Standardese, so I could have easily missed it).
The reason that the code snippet in question compiles is due to non-standard conforming behavior from Visual Studio (I'm currently using VS2017.3 Preview, which compiles the code without errors even with the /permissive- flag). Below is the error emitted by GCC and Clang:
Error(s):
source_file.cpp: In constructor ‘Derived::Derived()’:
source_file.cpp:25:20: error: call of overloaded ‘Other(Derived&)’ is ambiguous
Other(*this)
^
source_file.cpp:16:5: note: candidate: Other::Other(const Base&)
Other(const Base&)
^
source_file.cpp:12:5: note: candidate: Other::Other(const Other&)
Other(const Other&)
^
Error(s):
source_file.cpp:25:9: error: call to constructor of 'Other' is ambiguous
Other(*this)
^ ~~~~~
source_file.cpp:12:5: note: candidate constructor
Other(const Other&)
^
source_file.cpp:16:5: note: candidate constructor
Other(const Base&)
^
1 error generated.
Error output taken from http://rextester.com/.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With