After reading this I tried making such conversion with static_cast
:
class A;
class B {
public:
B(){}
B(const A&) //conversion constructor
{
cout << "called B's conversion constructor" << endl;
}
};
class A {
public:
operator B() const //conversion operator
{
cout << "called A's conversion operator" << endl;
return B();
}
};
int main()
{
A a;
//Original code, This is ambiguous,
//because both operator and constructor have same cv qualification (use -pedantic flag)
B b = a;
//Why isn't this ambiguous, Why is conversion constructor called,
//if both constructor and operator have same c-v qualification
B c = static_cast<B>(a);
return 0;
}
I expected it to not compile, because both constructor and operator have same c-v qualification. However it compiled, successfully and static_cast
calls constructor instead of operator. Why?
(compiled using gcc 4.8.1 with pedantic
and Wall
flags)
Static casting an object into their own type can call the copy constructor. When you use static_cast , by defaut (i.e. without optimizations activated) it calls the conversion constructor of the object you are trying to cast into (if it exists). For instance, in this code.
A conversion constructor is a single-parameter constructor that is declared without the function specifier explicit . The compiler uses conversion constructors to convert objects from the type of the first parameter to the type of the conversion constructor's class.
What you might not expect is that it does not invoke that function on the current object! Instead, the cast creates a new, temporary copy of the base class part of *this, then invokes onResize on the copy!
The static_cast operator converts variable j to type float . This allows the compiler to generate a division with an answer of type float . All static_cast operators resolve at compile time and do not remove any const or volatile modifiers.
The C++11 Standard says (emphasis mine):
5.2.9 Static cast
4 Otherwise, an expression
e
can be explicitly converted to a typeT
using astatic_cast
of the formstatic_cast<T>(e)
if the declarationT t(e);
is well-formed, for some invented temporary variablet
(8.5). The effect of such an explicit conversion is the same as performing the declaration and initialization and then using the temporary variable as the result of the conversion. The expressione
is used as a glvalue if and only if the initialization uses it as a glvalue.5 Otherwise, the
static_cast
shall perform one of the conversions listed below. No other conversion shall be performed explicitly using astatic_cast
.
That explains why the static_cast
in
B c = static_cast<B>(a);
ends up calling the constructor of B
.
The conversion operator is used only if the T t(e)
is not well-formed.
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