CSE 202: Computer Science II, Winter 2018
Conversions
Implicit conversions

Consider the code fragment int x = 3.5;. Even though the initializer value is 3.5, the initial value of x actually becomes 3. The first reason is because an integer object cannot store fractional values. The second reason is because 3.5 underwent implicit conversion during initialization.

Implicit conversion also happens when you invoke a function that expects a double argument, but you provide an int argument instead. An example of this happening is when an expression like std::cos(3) gets evaluated; the integer value 3 gets implicitly converted to the floating-point value 3.0.

The implicit conversions that happen between built-in types are known as the standard conversions.

Most of the standard conversions are common sense (such as the integer value 42 becoming 42.0 when being assigned to a double). Some are less common sense (such as non-zero values becoming true when converted to bool and vice versa).

Explicit conversions

An explicit conversion can be performed by the programmer. One way to do this is to have some expression preceeded by a type enclosed in parenthesis, for example (double)x is an explicit conversion of x to a value of type double. This method is known as cast notation, in this method we say that x is being "casted" to double.

functional notation is another way to make an explicit conversion. The expression double(x) also creates a value of type double from x (converting the value of x if necessary).

Converting constructor

A converting constructor is a constructor with a single parameter of a type that is different from the class that the constructor is for.

Here is a very abstract example of a class with a converting constructor:

class A { public: A(bool b) { } };

This class does nothing, but the following statements and expressions are now valid due to the presence of a boolean converting constructor in A:

When an class type object gets initialized with a value of a different type, the appropriate converting constructor gets invoked. You can have multiple converting constructors if there is more than one type that can be converted to your class.

explicit specifier

When a converting constructor for some class T is preceeded with the keyword explicit, then that converting constructor cannot be invoked through implicit conversion: an expression such as T x = U() becomes invalid; instead, direct initialization (T x(U());) or explicit conversion (T x = (T)U();) should be used to get the same effect.

explicit can also be used with copy constructors to disallow copy initialization but still allow direct initialization.

class A { public: explicit A(int b) {} }; class B { public: B(int x) {} }; int main() { A a(12); // OK: Direct initialization A b = A(4); // OK: Copy initialization from direct initialized nameless temporary A c = 10; // Compiler error: explicit disallows implicit conversion from 10 to A B d = 8; // OK: B's converting constructor has no explicit specifier. // Copy initialization from nameless temporary created from implicit conversion // of 8 allowed. return 0; }