{"id":67,"date":"2007-06-19T18:34:26","date_gmt":"2007-06-20T02:34:26","guid":{"rendered":"http:\/\/www.learncpp.com\/cpp-tutorial\/44-type-conversion-and-casting\/"},"modified":"2025-03-03T15:13:55","modified_gmt":"2025-03-03T23:13:55","slug":"implicit-type-conversion","status":"publish","type":"post","link":"https:\/\/www.learncpp.com\/cpp-tutorial\/implicit-type-conversion\/","title":{"rendered":"10.1 &#8212; Implicit type conversion"},"content":{"rendered":"<p>We introduced type conversion in lesson <a href=\"https:\/\/www.learncpp.com\/cpp-tutorial\/introduction-to-type-conversion-and-static_cast\/\">4.12 -- Introduction to type conversion and static_cast<\/a>.  To recap the most important points from that lesson:<\/p>\n<ul>\n<li>The process of converting data from one type to another type is called &#8220;type conversion&#8221;.\n<\/li>\n<li>Implicit type conversion is performed automatically by the compiler when one data type is required, but a different data type is supplied.\n<\/li>\n<li>Explicit type conversion is requested by using a cast operator, such as <code>static_cast<\/code>.\n<\/li>\n<li>Conversions do not change the data being converted.   Instead, the conversion process uses that data as input, and produces the converted result.\n<\/li>\n<li>When converting a value to another type of value, the conversion process produces a temporary object of the target type that holds the result of the conversion.\n<\/li>\n<\/ul>\n<p>In the first half of this chapter, we&#8217;re going to dig a bit deeper into how type conversion works.  We&#8217;ll start with implicit conversions in this lesson, and explicit type conversions (casting) in upcoming lesson <a href=\"https:\/\/www.learncpp.com\/cpp-tutorial\/explicit-type-conversion-casting-and-static-cast\/\">10.6 -- Explicit type conversion (casting) and static_cast<\/a>.  Since type conversion is used all over the place, having some understanding of what&#8217;s happening under the hood when a conversion is needed is important.  This knowledge is also relevant when for understanding how overloaded functions (functions that can have the same name as other functions) work.<\/p>\n<div class=\"cpp-note cpp-lightgraybackground\">\n<p class=\"cpp-note-title cpp-bottomline\">Author&#8217;s note<\/p>\n<p>In this chapter, we&#8217;ll focus on the conversion of values to other types of values.  We&#8217;ll cover other types of conversions once we introduce the prerequisite topics (such as pointers, references, inheritance, etc&#8230;).\n<\/p><\/div>\n<p class=\"cpp-section cpp-topline\" style=\"clear: both\">Why conversions are needed<\/p>\n<p>The value of an object is stored as a sequence of bits, and the data type of the object tells the compiler how to interpret those bits into meaningful values.  Different data types may represent the &#8220;same&#8221; value differently.  For example, the integer value <code>3<\/code> might be stored as binary <code>0000 0000 0000 0000 0000 0000 0000 0011<\/code>, whereas floating point value <code>3.0<\/code> might be stored as binary <code>0100 0000 0100 0000 0000 0000 0000 0000<\/code>.<\/p>\n<p style=\"clear: both\"><\/p> <!-- break around image -->\n<p>So what happens when we do something like this?<\/p>\n<pre class=\"language-cpp line-numbers\"><code class=\"language-cpp match-braces\">float f{ 3 }; \/\/ initialize floating point variable with int 3<\/code><\/pre>\n<p>In such a case, the compiler can&#8217;t just copy the bits used to represent <code>int<\/code> value <code>3<\/code> into the memory allocated for <code>float<\/code> variable <code>f<\/code>.  If it were to do so, then when <code>f<\/code> (which has type <code>float<\/code>) was evaluated, those bits would be interpreted as a <code>float<\/code> rather than an <code>int<\/code>, and who knows what <code>float<\/code> value we&#8217;d end up with!<\/p>\n<div class=\"cpp-note cpp-lightgraybackground\">\n<p class=\"cpp-note-title cpp-bottomline\">As an aside&#8230;<\/p>\n<p>The following program actually prints <code>int<\/code> value <code>3<\/code> as if it were a <code>float<\/code>:<\/p>\n<pre class=\"language-cpp line-numbers\"><code class=\"language-cpp match-braces\">#include &lt;iostream&gt;\r\n#include &lt;cstring&gt;\r\n\r\nint main()\r\n{\r\n    int n { 3 };                        \/\/ here's int value 3\r\n    float f {};                         \/\/ here's our float variable\r\n    std::memcpy(&amp;f, &amp;n, sizeof(float)); \/\/ copy the bits from n into f\r\n    std::cout &lt;&lt; f &lt;&lt; '\\n';             \/\/ print f (containing the bits from n)\r\n\r\n    return 0;\r\n}<\/code><\/pre>\n<p>This produces the following result:<\/p>\n<pre>\n4.2039e-45\r\n<\/pre>\n<\/div>\n<p>Instead, the integer value <code>3<\/code> needs to be converted into the equivalent floating point value <code>3.0<\/code>, which can then be stored in the memory allocated for <code>f<\/code> (using the bit representation for <code>float<\/code> value <code>3.0<\/code>) .<\/p>\n<p class=\"cpp-section cpp-topline\" style=\"clear: both\">When implicit type conversion happens<\/p>\n<p><strong>Implicit type conversion<\/strong> (also called <strong>automatic type conversion<\/strong> or <strong>coercion<\/strong>) is performed automatically by the compiler when an expression of some type is supplied in a context where some other type is expected.  The vast majority of type conversions in C++ are implicit type conversions.  For example, implicit type conversion happens in all of the following cases:<\/p>\n<p>When initializing (or assigning a value to) a variable with a value of a different data type:<\/p>\n<pre class=\"language-cpp line-numbers\"><code class=\"language-cpp match-braces\">double d{ 3 }; \/\/ int value 3 implicitly converted to type double\r\nd = 6; \/\/ int value 6 implicitly converted to type double<\/code><\/pre>\n<p>When the type of a return value is different from the function&#8217;s declared return type:<\/p>\n<pre class=\"language-cpp line-numbers\"><code class=\"language-cpp match-braces\">float doSomething()\r\n{\r\n    return 3.0; \/\/ double value 3.0 implicitly converted to type float\r\n}<\/code><\/pre>\n<p>When using certain binary operators with operands of different types:<\/p>\n<pre class=\"language-cpp line-numbers\"><code class=\"language-cpp match-braces\">double division{ 4.0 \/ 3 }; \/\/ int value 3 implicitly converted to type double<\/code><\/pre>\n<p>When using a non-Boolean value in an if-statement:<\/p>\n<pre class=\"language-cpp line-numbers\"><code class=\"language-cpp match-braces\">if (5) \/\/ int value 5 implicitly converted to type bool\r\n{\r\n}<\/code><\/pre>\n<p>When an argument passed to a function is a different type than the function parameter:<\/p>\n<pre class=\"language-cpp line-numbers\"><code class=\"language-cpp match-braces\">void doSomething(long l)\r\n{\r\n}\r\n\r\ndoSomething(3); \/\/ int value 3 implicitly converted to type long<\/code><\/pre>\n<p>So how does the compiler know how to convert a value to a different type anyway?<\/p>\n<p class=\"cpp-section cpp-topline\" style=\"clear: both\">The standard conversions<\/p>\n<p>As part of the core language, the C++ standard defines a collection of conversion rules known as the &#8220;standard conversions&#8221;.  The <strong>standard conversions<\/strong> specify how various fundamental types (and certain compound types, including arrays, references, pointers, and enumerations) convert to other types within that same group.<\/p>\n<p>As of C++23, there are 14 different standard conversions.  These can be roughly grouped into 5 general categories:<\/p>\n<div class=\"cpp-table-wrapper\">\n<table class=\"cpp-table\">\n<tr>\n<th> Category <\/th>\n<th> Meaning <\/th>\n<th> Link <\/th>\n<\/tr>\n<tr>\n<td> Numeric promotions <\/td>\n<td> Conversions of small integral types to <code>int<\/code> or <code>unsigned int<\/code>, and of <code>float<\/code> to <code>double<\/code>. <\/td>\n<td> <a href=\"https:\/\/www.learncpp.com\/cpp-tutorial\/floating-point-and-integral-promotion\/\">10.2 -- Floating-point and integral promotion<\/a> <\/td>\n<\/tr>\n<tr>\n<td> Numeric conversions <\/td>\n<td> Other integral and floating point conversions that aren&#8217;t promotions. <\/td>\n<td> <a href=\"https:\/\/www.learncpp.com\/cpp-tutorial\/numeric-conversions\/\">10.3 -- Numeric conversions<\/a> <\/td>\n<\/tr>\n<tr>\n<td> Qualification conversions <\/td>\n<td> Conversions that add or remove <code>const<\/code> or <code>volatile<\/code>. <\/td>\n<td> <\/td>\n<\/tr>\n<tr>\n<td> Value transformations <\/td>\n<td> Conversions that change the value category of an expression <\/td>\n<td> <a href=\"https:\/\/www.learncpp.com\/cpp-tutorial\/value-categories-lvalues-and-rvalues\/\">12.2 -- Value categories (lvalues and rvalues)<\/a> <\/td>\n<\/tr>\n<tr>\n<td> Pointer conversions <\/td>\n<td> Conversions from <code>std::nullptr<\/code> to pointer types, or pointer types to other pointer types <\/td>\n<td> <\/td>\n<\/tr>\n<\/table>\n<\/div>\n<p>For example, converting an <code>int<\/code> value to a <code>float<\/code> value falls under the numeric conversions category, so the compiler to perform such a conversion, the compiler simply need apply the <code>int<\/code> to <code>float<\/code> numeric conversion rules.<\/p>\n<p>The numeric conversions and numeric promotions are the most important of these categories, and we&#8217;ll cover them in more detail in upcoming lessons.<\/p>\n<div class=\"cpp-note cpp-lightgraybackground\">\n<p class=\"cpp-note-title cpp-bottomline\">For advanced readers<\/p>\n<p>Here is the full list of standard conversions:<\/p>\n<div class=\"cpp-table-wrapper\">\n<table class=\"cpp-table\">\n<tr>\n<th> Category <\/th>\n<th> Standard Conversion <\/th>\n<th> Description <\/th>\n<th> Also See <\/th>\n<\/tr>\n<tr>\n<td> Value transformation <\/td>\n<td> Lvalue-to-rvalue <\/td>\n<td> Converts lvalue expression to rvalue expression <\/td>\n<td> <a href=\"https:\/\/www.learncpp.com\/cpp-tutorial\/value-categories-lvalues-and-rvalues\/\">12.2 -- Value categories (lvalues and rvalues)<\/a> <\/td>\n<\/tr>\n<tr>\n<td> Value transformation <\/td>\n<td> Array-to-pointer <\/td>\n<td> Converts C-style array to pointer to first array element (a.k.a. array decay) <\/td>\n<td> <a href=\"https:\/\/www.learncpp.com\/cpp-tutorial\/c-style-array-decay\/\">17.8 -- C-style array decay<\/a> <\/td>\n<\/tr>\n<tr>\n<td> Value transformation <\/td>\n<td> Function-to-pointer <\/td>\n<td> Converts function to function pointer <\/td>\n<td> <a href=\"https:\/\/www.learncpp.com\/cpp-tutorial\/function-pointers\/\">20.1 -- Function Pointers<\/a> <\/td>\n<\/tr>\n<tr>\n<td> Value transformation <\/td>\n<td> Temporary materialization <\/td>\n<td> Converts value to temporary object <\/td>\n<td> <\/td>\n<\/tr>\n<tr>\n<td> Qualification conversion <\/td>\n<td> Qualification conversion <\/td>\n<td> Adds or removes <code>const<\/code> or <code>volatile<\/code> from types <\/td>\n<td> <\/td>\n<\/tr>\n<tr>\n<td> Numeric promotions <\/td>\n<td> Integral promotions <\/td>\n<td> Converts smaller integral types to <code>int<\/code> or <code>unsigned int<\/code> <\/td>\n<td>  <a href=\"https:\/\/www.learncpp.com\/cpp-tutorial\/floating-point-and-integral-promotion\/\">10.2 -- Floating-point and integral promotion<\/a> <\/td>\n<\/tr>\n<tr>\n<td> Numeric promotions <\/td>\n<td> Floating point promotions <\/td>\n<td> Converts <code>float<\/code> to <code>double<\/code> <\/td>\n<td> <a href=\"https:\/\/www.learncpp.com\/cpp-tutorial\/floating-point-and-integral-promotion\/\">10.2 -- Floating-point and integral promotion<\/a> <\/td>\n<\/tr>\n<tr>\n<td> Numeric conversions <\/td>\n<td> Integral conversions <\/td>\n<td> Integral conversions that aren&#8217;t integral promotions <\/td>\n<td> <a href=\"https:\/\/www.learncpp.com\/cpp-tutorial\/numeric-conversions\/\">10.3 -- Numeric conversions<\/a> <\/td>\n<\/tr>\n<tr>\n<td> Numeric conversions <\/td>\n<td> Floating point conversions <\/td>\n<td> Floating point conversions that aren&#8217;t floating point promotions <\/td>\n<td> <a href=\"https:\/\/www.learncpp.com\/cpp-tutorial\/numeric-conversions\/\">10.3 -- Numeric conversions<\/a> <\/td>\n<\/tr>\n<tr>\n<td> Numeric conversions <\/td>\n<td> Integral-floating conversions <\/td>\n<td> Converts integral and floating point types <\/td>\n<td> <a href=\"https:\/\/www.learncpp.com\/cpp-tutorial\/numeric-conversions\/\">10.3 -- Numeric conversions<\/a> <\/td>\n<\/tr>\n<tr>\n<td> Numeric conversions <\/td>\n<td> Boolean conversions <\/td>\n<td> Converts integral, unscoped enumeration, pointer, or pointer-to-memver to bool <\/td>\n<td> <a href=\"https:\/\/www.learncpp.com\/cpp-tutorial\/introduction-to-if-statements\/\">4.10 -- Introduction to if statements<\/a> <\/td>\n<\/tr>\n<tr>\n<td> Pointer conversions <\/td>\n<td> Pointer conversions <\/td>\n<td> Converts <code>std::nullptr<\/code> to pointer, or pointer to void pointer or base class <\/td>\n<td> <\/td>\n<\/tr>\n<tr>\n<td> Pointer conversions <\/td>\n<td> Pointer-to-member conversions <\/td>\n<td> Converts <code>std::nullptr<\/code> to pointer-to-member<br \/>or pointer-to-member of base class to pointer-to-member of derived class <\/td>\n<td> <\/td>\n<\/tr>\n<tr>\n<td> Pointer conversions <\/td>\n<td> Function pointer conversions <\/td>\n<td> Converts pointer-to-noexcept-function to pointer-to-function <\/td>\n<td> <\/td>\n<\/tr>\n<\/table>\n<\/div>\n<\/div>\n<p class=\"cpp-section cpp-topline\" style=\"clear: both\">Type conversion can fail<\/p>\n<p>When a type conversion is invoked (whether implicitly or explicitly), the compiler will determine whether it can convert the value from the current type to the desired type. If a valid conversion can be found, then the compiler will produce a new value of the desired type.<\/p>\n<p>If the compiler can\u2019t find an acceptable conversion, then the compilation will fail with a compile error.   Type conversions can fail for any number of reasons. For example, the compiler might not know how to convert a value between the original type and the desired type.<\/p>\n<p>For example:<\/p>\n<pre class=\"language-cpp line-numbers\"><code class=\"language-cpp match-braces\">int main()\r\n{\r\n    int x { \"14\" };\r\n\r\n    return 0;\r\n}<\/code><\/pre>\n<p>The because there isn&#8217;t a standard conversion from the string literal &#8220;14&#8221; to <code>int<\/code>, the compiler will produce an error.  For example, GCC produces the error: <code>prog.cc:3:13: error: invalid conversion from 'const char*' to 'int' [-fpermissive]<\/code>.<\/p>\n<p>In other cases, specific features may disallow some categories of conversions. For example:<\/p>\n<pre class=\"language-cpp line-numbers\"><code class=\"language-cpp match-braces\">int x { 3.5 }; \/\/ brace-initialization disallows conversions that result in data loss<\/code><\/pre>\n<p>Even though the compiler knows how to convert a <code>double<\/code> value to an <code>int<\/code> value, narrowing conversions are disallowed when using brace-initialization.<\/p>\n<p>There are also cases where the compiler may not be able to figure out which of several possible type conversions is the best one to use.  We&#8217;ll see examples of this in lesson <a href=\"https:\/\/www.learncpp.com\/cpp-tutorial\/function-overload-resolution-and-ambiguous-matches\/\">11.3 -- Function overload resolution and ambiguous matches<\/a>.<\/p>\n<p>The full set of rules describing how type conversions work is both lengthy and complicated, and for the most part, type conversion &#8220;just works&#8221;.  In the next set of lessons, we&#8217;ll cover the most important things you need to know about the standard conversions.  If finer detail is required for some uncommon case, the full rules are detailed in <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/implicit_conversion\">technical reference documentation for implicit conversions<\/a>.<\/p>\n<p>Let&#8217;s get to it!<\/p>\n<div class=\"prevnext\"><div class=\"prevnext-inline\">\n\t<a class=\"nav-link\" href=\"https:\/\/www.learncpp.com\/cpp-tutorial\/floating-point-and-integral-promotion\/\">\n <div class=\"nav-button nav-button-next\">\n    <div class=\"nav-button-icon\"><i class=\"fa fa-chevron-circle-right\" aria-hidden=\"true\"><\/i><\/div>\n    <div class=\"nav-button-text\">\n      <div class=\"nav-button-title\">Next lesson<\/div>\n      <div class=\"nav-button-lesson\">\n        <span class=\"nav-button-lesson-number\">10.2<\/span>Floating-point and integral promotion\n      <\/div>\n    <\/div>\n  <\/div><\/a>\n  \t<a class=\"nav-link\" href=\"\/\">\n  <div class=\"nav-button nav-button-index\">\n    <div class=\"nav-button-icon\"><i class=\"fa fa-home\" aria-hidden=\"true\"><\/i><\/div>\n    <div class=\"nav-button-text\">\n      <div class=\"nav-button-title\">Back to table of contents<\/div>\n    <\/div>\n<\/div><\/a>\n  \t<a class=\"nav-link\" href=\"https:\/\/www.learncpp.com\/cpp-tutorial\/chapter-9-summary-and-quiz\/\">\n  <div class=\"nav-button nav-button-prev\">\n    <div class=\"nav-button-icon\"><i class=\"fa fa-chevron-circle-left\" aria-hidden=\"true\"><\/i><\/div>\n    <div class=\"nav-button-text\">\n      <div class=\"nav-button-title\">Previous lesson<\/div>\n      <div class=\"nav-button-lesson\">\n        <span class=\"nav-button-lesson-number\">9.x<\/span>Chapter 9 summary and quiz\n      <\/div>\n    <\/div>\n  <\/div><\/a>\n  <\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>We introduced type conversion in lesson . To recap the most important points from that lesson: The process of converting data from one type to another type is called &#8220;type conversion&#8221;. Implicit type conversion is performed automatically by the compiler when one data type is required, but a different data &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[],"_links":{"self":[{"href":"https:\/\/www.learncpp.com\/wp-json\/wp\/v2\/posts\/67"}],"collection":[{"href":"https:\/\/www.learncpp.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.learncpp.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.learncpp.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.learncpp.com\/wp-json\/wp\/v2\/comments?post=67"}],"version-history":[{"count":33,"href":"https:\/\/www.learncpp.com\/wp-json\/wp\/v2\/posts\/67\/revisions"}],"predecessor-version":[{"id":18235,"href":"https:\/\/www.learncpp.com\/wp-json\/wp\/v2\/posts\/67\/revisions\/18235"}],"wp:attachment":[{"href":"https:\/\/www.learncpp.com\/wp-json\/wp\/v2\/media?parent=67"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.learncpp.com\/wp-json\/wp\/v2\/categories?post=67"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.learncpp.com\/wp-json\/wp\/v2\/tags?post=67"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}