<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Learn C++</title>
	<atom:link href="https://www.learncpp.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.learncpp.com</link>
	<description>Skill up with our free tutorials</description>
	<lastBuildDate>Fri, 14 Feb 2025 05:42:48 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://www.learncpp.com/blog/wp-content/uploads/learncpp.png</url>
	<title>Learn C++</title>
	<link>https://www.learncpp.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>F.X &#8212; Chapter F summary and quiz</title>
		<link>https://www.learncpp.com/cpp-tutorial/chapter-f-summary-and-quiz/</link>
					<comments>https://www.learncpp.com/cpp-tutorial/chapter-f-summary-and-quiz/#comments</comments>
		
		<dc:creator><![CDATA[Alex]]></dc:creator>
		<pubDate>Mon, 02 Dec 2024 19:32:07 +0000</pubDate>
				<category><![CDATA[C++ Tutorial]]></category>
		<guid isPermaLink="false">https://www.learncpp.com/?p=17932</guid>

					<description><![CDATA[A constexpr function is a function that is allowed to be called in a constant expression. To make a function a constexpr function, we simply use the constexpr keyword in front of the return type. Constexpr functions are only guaranteed to be evaluated at compile-time when used in a context &#8230;]]></description>
										<content:encoded><![CDATA[<p>A <strong>constexpr</strong> function is a function that is allowed to be called in a constant expression.  To make a function a constexpr function, we simply use the <code>constexpr</code> keyword in front of the return type.  Constexpr functions are only guaranteed to be evaluated at compile-time when used in a context that requires a constant expression.  Otherwise they may be evaluated at compile-time (if eligible) or runtime.  Constexpr functions are implicitly inline, and the compiler must see the full definition of the constexpr function to call it at compile-time.</p>
<p>A <strong>consteval function</strong> is a function that must evaluate at compile-time.  Consteval functions otherwise follow the same rules as constexpr functions.</p>
<p class="cpp-section cpp-topline" style="clear: both">Quiz time</p>
<p class="cpp-quiz-question" style="clear: both">Question #1</p>
<p>Add <code>const</code> and/or <code>constexpr</code> to the following program:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

// gets tower height from user and returns it
double getTowerHeight()
{
	std::cout &lt;&lt; "Enter the height of the tower in meters: ";
	double towerHeight{};
	std::cin &gt;&gt; towerHeight;
	return towerHeight;
}

// Returns ball height from ground after "seconds" seconds
double calculateBallHeight(double towerHeight, int seconds)
{
	double gravity{ 9.8 };

	// Using formula: [ s = u * t + (a * t^2) / 2 ], here u(initial velocity) = 0
	double distanceFallen{ (gravity * (seconds * seconds)) / 2.0 };
	double currentHeight{ towerHeight - distanceFallen };

	return currentHeight;
}

// Prints ball height above ground
void printBallHeight(double ballHeight, int seconds)
{
	if (ballHeight &gt; 0.0)
		std::cout &lt;&lt; "At " &lt;&lt; seconds &lt;&lt; " seconds, the ball is at height: " &lt;&lt; ballHeight &lt;&lt; " meters\n";
	else
		std::cout &lt;&lt; "At " &lt;&lt; seconds &lt;&lt; " seconds, the ball is on the ground.\n";
}

// Calculates the current ball height and then prints it
// This is a helper function to make it easier to do this
void printCalculatedBallHeight(double towerHeight, int seconds)
{
	double ballHeight{ calculateBallHeight(towerHeight, seconds) };
	printBallHeight(ballHeight, seconds);
}

int main()
{
	double towerHeight{ getTowerHeight() };

	printCalculatedBallHeight(towerHeight, 0);
	printCalculatedBallHeight(towerHeight, 1);
	printCalculatedBallHeight(towerHeight, 2);
	printCalculatedBallHeight(towerHeight, 3);
	printCalculatedBallHeight(towerHeight, 4);
	printCalculatedBallHeight(towerHeight, 5);

	return 0;
}</code></pre>
<p><a class="solution_link_show" href="javascript:void(0)" onclick="cppSolutionToggle(document.getElementById('cpp_solution_id_0'), this, 'Show Solution', 'Hide Solution')">Show Solution</a></p>
<div class="wpsolution" id="cpp_solution_id_0" style="display:none">
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

// This function should not be made constexpr because output and input can only be done at runtime.
// The versions of `operator&lt;&lt;` and `operator&gt;&gt;` that do output and input don't support constexpr.
double getTowerHeight()
{
	std::cout &lt;&lt; "Enter the height of the tower in meters: ";
	double towerHeight{};
	std::cin &gt;&gt; towerHeight;
	return towerHeight;
}

// Returns height from ground after "seconds" seconds
// This function is made constepxr because it just calculates a value from its inputs and return it.
// Arithmetic can be done at compile-time, and no non-constexpr functions are called.
// Reminder: A constexpr function can be evaluated at compile-time or runtime.
//   If its arguments are constexpr, it can be called at compile-time.
//   In this case, it's called at runtime because the argument for towerHeight isn't constexpr.
// If a function can be made constexpr, it should be.
// Remember: function parameters are not constexpr, even in a constexpr function
constexpr double calculateBallHeight(double towerHeight, int seconds)
{
	constexpr double gravity{ 9.8 }; // constexpr because it's a compile-time constant

	// Using formula: [ s = u * t + (a * t^2) / 2 ], here u(initial velocity) = 0
	// These variables can't be constexpr since their initializers aren't constant expressions
	const double distanceFallen{ (gravity * (seconds * seconds)) / 2.0 };
	const double currentHeight{ towerHeight - distanceFallen };

	return currentHeight;
}

// This function should not be made constexpr because output and input can only be done at runtime.
// The versions of `operator&lt;&lt;` and `operator&gt;&gt;` that do output and input don't support constexpr.
void printBallHeight(double ballHeight, int seconds)
{
	if (ballHeight &gt; 0.0)
		std::cout &lt;&lt; "At " &lt;&lt; seconds &lt;&lt; " seconds, the ball is at height: " &lt;&lt; ballHeight &lt;&lt; " meters\n";
	else
		std::cout &lt;&lt; "At " &lt;&lt; seconds &lt;&lt; " seconds, the ball is on the ground.\n";
}

// This function should not be made constexpr because output and input can only be done at runtime.
// The versions of `operator&lt;&lt;` and `operator&gt;&gt;` that do output and input don't support constexpr.
void printCalculatedBallHeight(double towerHeight, int seconds)
{
	// height can only be const (not constexpr) because its initializer is not a constant expression
	const double ballHeight{ calculateBallHeight(towerHeight, seconds) };
	printBallHeight(ballHeight, seconds);
}

int main()
{
	// towerHeight can only be const (not constexpr) because its initializer is not a constant expression
	const double towerHeight{ getTowerHeight() };

	printCalculatedBallHeight(towerHeight, 0);
	printCalculatedBallHeight(towerHeight, 1);
	printCalculatedBallHeight(towerHeight, 2);
	printCalculatedBallHeight(towerHeight, 3);
	printCalculatedBallHeight(towerHeight, 4);
	printCalculatedBallHeight(towerHeight, 5);

	return 0;
}</code></pre>
</div>
<div class="prevnext"><div class="prevnext-inline">
	<a class="nav-link" href="https://www.learncpp.com/cpp-tutorial/introduction-to-compound-data-types/">
 <div class="nav-button nav-button-next">
    <div class="nav-button-icon"><i class="fa fa-chevron-circle-right" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Next lesson</div>
      <div class="nav-button-lesson">
        <span class="nav-button-lesson-number">12.1</span>Introduction to compound data types
      </div>
    </div>
  </div></a>
  	<a class="nav-link" href="/">
  <div class="nav-button nav-button-index">
    <div class="nav-button-icon"><i class="fa fa-home" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Back to table of contents</div>
    </div>
</div></a>
  	<a class="nav-link" href="https://www.learncpp.com/cpp-tutorial/constexpr-functions-part-4/">
  <div class="nav-button nav-button-prev">
    <div class="nav-button-icon"><i class="fa fa-chevron-circle-left" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Previous lesson</div>
      <div class="nav-button-lesson">
        <span class="nav-button-lesson-number">F.4</span>Constexpr functions (part 4)
      </div>
    </div>
  </div></a>
  </div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.learncpp.com/cpp-tutorial/chapter-f-summary-and-quiz/feed/</wfw:commentRss>
			<slash:comments>11</slash:comments>
		
		
			</item>
		<item>
		<title>F.4 &#8212; Constexpr functions (part 4)</title>
		<link>https://www.learncpp.com/cpp-tutorial/constexpr-functions-part-4/</link>
					<comments>https://www.learncpp.com/cpp-tutorial/constexpr-functions-part-4/#comments</comments>
		
		<dc:creator><![CDATA[Alex]]></dc:creator>
		<pubDate>Wed, 27 Nov 2024 00:49:45 +0000</pubDate>
				<category><![CDATA[C++ Tutorial]]></category>
		<guid isPermaLink="false">https://www.learncpp.com/?p=17892</guid>

					<description><![CDATA[Constexpr/consteval functions can use non-const local variables Within a constexpr or consteval function, we can use local variables that are not constexpr, and the value of these variables can be changed. As a silly example: #include &#60;iostream&#62; consteval int doSomething(int x, int y) // function is consteval { x = &#8230;]]></description>
										<content:encoded><![CDATA[<p class="cpp-section">Constexpr/consteval functions can use non-const local variables</p>
<p>Within a constexpr or consteval function, we can use local variables that are not constexpr, and the value of these variables can be changed.</p>
<p>As a silly example:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

consteval int doSomething(int x, int y) // function is consteval
{
    x = x + 2;       // we can modify the value of non-const function parameters

    int z { x + y }; // we can instantiate non-const local variables
    if (x &gt; y)
        z = z - 1;   // and then modify their values

    return z;
}

int main()
{
    constexpr int g { doSomething(5, 6) };
    std::cout &lt;&lt; g &lt;&lt; '\n';

    return 0;
}</code></pre>
<p>When such functions are evaluated at compile-time, the compiler will essentially &#8220;execute&#8221; the function and return the calculated value.</p>
<p class="cpp-section cpp-topline" style="clear: both">Constexpr/consteval functions can use function parameters and local variables as arguments in constexpr function calls</p>
<p>Above, we noted, &#8220;When a constexpr (or consteval) function is being evaluated at compile-time, any other functions it calls are required to be evaluated at compile-time.&#8221;</p>
<p>Perhaps surprisingly, a constexpr or consteval function can use its function parameters (which aren&#8217;t constexpr) or even local variables (which may not be const at all) as arguments in a constexpr function call.  When a constexpr or consteval function is being evaluated at compile-time, the value of all function parameters and local variables must be known to the compiler (otherwise it couldn&#8217;t evaluate them at compile-time).  Therefore, in this specific context, C++ allows these values to be used as arguments in a call to a constexpr function, and that constexpr function call can still be evaluated at compile-time.</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

constexpr int goo(int c) // goo() is now constexpr
{
    return c;
}

constexpr int foo(int b) // b is not a constant expression within foo()
{
    return goo(b);       // if foo() is resolved at compile-time, then `goo(b)` can also be resolved at compile-time
}

int main()
{
    std::cout &lt;&lt; foo(5);
    
    return 0;
}</code></pre>
<p>In the above example, <code>foo(5)</code> may or may not be evaluated at compile time.  If it is, then the compiler knows that <code>b</code> is <code>5</code>.  And even though <code>b</code> is not constexpr, the compiler can treat the call to <code>goo(b)</code> as if it were <code>goo(5)</code> and evaluate that function call at compile-time.  If <code>foo(5)</code> is instead resolved at runtime, then <code>goo(b)</code> will also be resolved at runtime.</p>
<p class="cpp-section cpp-topline" style="clear: both">Can a constexpr function call a non-constexpr function?</p>
<p>The answer is yes, but only when the constexpr function is being evaluated in a non-constant context.  A non-constexpr function may not be called when a constexpr function is evaluating in a constant context (because then the constexpr function wouldn&#8217;t be able to produce a compile-time constant value), and doing so will produce a compilation error.</p>
<p>Calling a non-constexpr function is allowed so that a constexpr function can do something like this:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;type_traits&gt; // for std::is_constant_evaluated

constexpr int someFunction()
{
    if (std::is_constant_evaluated()) // if evaluating in constant context
        return someConstexprFcn();
    else
        return someNonConstexprFcn();
}</code></pre>
<p>Now consider this variant:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">constexpr int someFunction(bool b)
{
    if (b)
        return someConstexprFcn();
    else
        return someNonConstexprFcn();
}</code></pre>
<p>This is legal as long as <code>someFunction(false)</code> is never called in a constant expression.</p>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">As an aside&#8230;</p>
<p>Prior to C++23, the C++ standard says that a constexpr function must return a constexpr value for at least one set of arguments, otherwise it is technically ill-formed.  Calling a non-constexpr function unconditionally in a constexpr function makes the constexpr function ill-formed.  However, compilers are not required to generate errors or warnings for such cases -- therefore, the compiler probably won&#8217;t complain unless you try to call such a constexpr function in a constant context.  In C++23, this requirement was rescinded.
</p></div>
<p>For best results, we&#8217;d advise the following:</p>
<ol start="1">
<li>Avoid calling non-constexpr functions from within a constexpr function if possible.
</li>
<li>If your constexpr function requires different behavior for constant and non-constant contexts, conditionalize the behavior with <code>if (std::is_constant_evaluated())</code> (in C++20) or <code>if consteval</code> (C++23 onward).
</li>
<li>Always test your constexpr functions in a constant context, as they may work when called in a non-constant context but fail in a constant context.
</li>
</ol>
<p class="cpp-section cpp-topline" style="clear: both">When should I constexpr a function?</p>
<p>As a general rule, if a function can be evaluated as part of a required constant expression, it should be made <code>constexpr</code>.</p>
<p>A <strong>pure function</strong> is a function that meets the following criteria:</p>
<ul>
<li>The function always returns the same return result when given the same arguments
</li>
<li>The function has no side effects (e.g. it doesn&#8217;t change the value of static local or global variables, doesn&#8217;t do input or output, etc&#8230;).
</li>
</ul>
<p>Pure functions should generally be made constexpr.</p>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">As an aside&#8230;</p>
<p>Constexpr functions don&#8217;t always need to be pure.  In C++23, constexpr functions can use and modify static local variables.  Since the value of a static local persists across function calls, modifying a static local variable is considered a side-effect.
</p></div>
<p>That said, if your program is trivial or a throw-away and you don&#8217;t constexpr a function, the world isn&#8217;t going to end.  Hopefully.</p>
<div class="cpp-note cpp-lightgreenbackground">
<p class="cpp-note-title cpp-bottomline">Best practice</p>
<p>Unless you have a specific reason not to, a function that can be evaluated as part of a constant expression should be made <code>constexpr</code> (even if it isn&#8217;t currently used that way).</p>
<p>A function that cannot be evaluated as part of a required constant expression should not be marked as <code>constexpr</code>.
</div>
<p class="cpp-section cpp-topline" style="clear: both">Why not constexpr every function?</p>
<p>There are a few reasons you may not want to <code>constexpr</code> a function:</p>
<ol start="1">
<li><code>constexpr</code> signals that a function can be used in a constant expression.  If your function cannot be evaluated as part of a constant expression, it should not be marked as <code>constexpr</code>.
</li>
<li><code>constexpr</code> is part of the interface of a function.  Once a function is made constexpr, it can be called by other constexpr functions or used in contexts that require constant expressions.  Removing the <code>constexpr</code> later will break such code.
</li>
<li><code>constexpr</code> makes functions harder to debug because you can&#8217;t inspect them at runtime.
</li>
</ol>
<p class="cpp-section cpp-topline" style="clear: both"><a name="constexprruntimeeval"></a>Why constexpr a function when it is not actually evaluated at compile-time? <a href="#constexprruntimeeval"><i class="fa fa-link" style="font-size: 0.8em;"></i></a></p>
<p>New programmers sometimes ask, &#8220;why should I constexpr a function when it is only evaluated at runtime in my program (e.g. because the arguments in the function call are non-const)&#8221;?</p>
<p>There are a few reasons:</p>
<ol start="1">
<li>There&#8217;s little downside to using constexpr, and it may help the compiler optimize your program to be smaller and faster.
</li>
<li>Just because you&#8217;re not calling the function in a compile-time evaluatable context right now doesn&#8217;t mean you won&#8217;t call it in such a context when you modify or extend your program.  And if you haven&#8217;t constexpr&#8217;d the function already, you may not think to when you do start to call it in such a context, and then you&#8217;ll miss out on the performance benefits.  Or you may be forced to constexpr it later when you need to use the return value in a context that requires a constant expression somewhere.
</li>
<li>Repetition helps ingrain best practices.
</li>
</ol>
<p>On a non-trivial project, it&#8217;s a good idea to implement your functions with the mindset that they may be reused (or extended) in the future.  Any time you modify an existing function, you risk breaking it, and that means it needs to be retested, which takes time and energy.  It&#8217;s often worth spending an extra minute or two &#8220;doing it right the first time&#8221; so you don&#8217;t have to redo (and retest) it again later.</p>
<div class="prevnext"><div class="prevnext-inline">
	<a class="nav-link" href="https://www.learncpp.com/cpp-tutorial/chapter-f-summary-and-quiz/">
 <div class="nav-button nav-button-next">
    <div class="nav-button-icon"><i class="fa fa-chevron-circle-right" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Next lesson</div>
      <div class="nav-button-lesson">
        <span class="nav-button-lesson-number">F.X</span>Chapter F summary and quiz
      </div>
    </div>
  </div></a>
  	<a class="nav-link" href="/">
  <div class="nav-button nav-button-index">
    <div class="nav-button-icon"><i class="fa fa-home" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Back to table of contents</div>
    </div>
</div></a>
  	<a class="nav-link" href="https://www.learncpp.com/cpp-tutorial/constexpr-functions-part-3-and-consteval/">
  <div class="nav-button nav-button-prev">
    <div class="nav-button-icon"><i class="fa fa-chevron-circle-left" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Previous lesson</div>
      <div class="nav-button-lesson">
        <span class="nav-button-lesson-number">F.3</span>Constexpr functions (part 3) and consteval
      </div>
    </div>
  </div></a>
  </div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.learncpp.com/cpp-tutorial/constexpr-functions-part-4/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>F.3 &#8212; Constexpr functions (part 3) and consteval</title>
		<link>https://www.learncpp.com/cpp-tutorial/constexpr-functions-part-3-and-consteval/</link>
					<comments>https://www.learncpp.com/cpp-tutorial/constexpr-functions-part-3-and-consteval/#comments</comments>
		
		<dc:creator><![CDATA[Alex]]></dc:creator>
		<pubDate>Wed, 27 Nov 2024 00:49:38 +0000</pubDate>
				<category><![CDATA[C++ Tutorial]]></category>
		<guid isPermaLink="false">https://www.learncpp.com/?p=17891</guid>

					<description><![CDATA[Forcing a constexpr function to be evaluated at compile-time There is no way to tell the compiler that a constexpr function should prefer to evaluate at compile-time whenever it can (e.g. in cases where the return value of a constexpr function is used in a non-constant expression). However, we can &#8230;]]></description>
										<content:encoded><![CDATA[<p class="cpp-section">Forcing a constexpr function to be evaluated at compile-time</p>
<p>There is no way to tell the compiler that a constexpr function should prefer to evaluate at compile-time whenever it can (e.g. in cases where the return value of a constexpr function is used in a non-constant expression).</p>
<p>However, we can force a constexpr function that is eligible to be evaluated at compile-time to actually evaluate at compile-time by ensuring the return value is used where a constant expression is required.  This needs to be done on a per-call basis.</p>
<p>The most common way to do this is to use the return value to initialize a constexpr variable (this is why we&#8217;ve been using variable &#8216;g&#8217; in prior examples).  Unfortunately, this requires introducing a new variable into our program just to ensure compile-time evaluation, which is ugly and reduces code readability.</p>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">For advanced readers</p>
<p>There are several hacky ways that people have tried to work around the problem of having to introduce a new constexpr variable each time we want to force compile-time evaluation.  See <a href="https://quuxplusone.github.io/blog/2018/08/07/force-constexpr/">here</a> and <a href="https://artificial-mind.net/blog/2020/11/14/cpp17-consteval">here</a>.
</div>
<p>However, in C++20, there is a better workaround to this issue, which we&#8217;ll present in a moment.</p>
<p class="cpp-section cpp-topline" style="clear: both">Consteval <span class="cpp-section-pill cpp-section-standard">C++20</span></p>
<p>C++20 introduces the keyword <strong>consteval</strong>, which is used to indicate that a function <em>must</em> evaluate at compile-time, otherwise a compile error will result.  Such functions are called <strong>immediate functions</strong>.</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

consteval int greater(int x, int y) // function is now consteval
{
    return (x &gt; y ? x : y);
}

int main()
{
    constexpr int g { greater(5, 6) };              // ok: will evaluate at compile-time
    std::cout &lt;&lt; g &lt;&lt; '\n';

    std::cout &lt;&lt; greater(5, 6) &lt;&lt; " is greater!\n"; // ok: will evaluate at compile-time

    int x{ 5 }; // not constexpr
    std::cout &lt;&lt; greater(x, 6) &lt;&lt; " is greater!\n"; // error: consteval functions must evaluate at compile-time

    return 0;
}</code></pre>
<p>In the above example, the first two calls to <code>greater()</code> will evaluate at compile-time.  The call to <code>greater(x, 6)</code> cannot be evaluated at compile-time, so a compile error will result.</p>
<div class="cpp-note cpp-lightgreenbackground">
<p class="cpp-note-title cpp-bottomline">Best practice</p>
<p>Use <code>consteval</code> if you have a function that must evaluate at compile-time for some reason (e.g. because it does something that can only be done at compile time).
</div>
<p>Perhaps surprisingly, the parameters of a consteval function are not constexpr (even though consteval functions can only be evaluated at compile-time).  This decision was made for the sake of consistency.</p>
<p class="cpp-section cpp-topline" style="clear: both">Using consteval to make constexpr execute at compile-time <span class="cpp-section-pill cpp-section-standard">C++20</span></p>
<p>The downside of consteval functions is that such functions can&#8217;t evaluate at runtime, making them less flexible than constexpr functions, which can do either.  Therefore, it would still be useful to have a convenient way to force constexpr functions to evaluate at compile-time (even when the return value is being used where a constant expression is not required), so that we could have compile-time evaluation when possible, and runtime evaluation when we can&#8217;t.</p>
<p>Consteval functions provides a way to make this happen, using a neat helper function:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

// Uses abbreviated function template (C++20) and `auto` return type to make this function work with any type of value
// See 'related content' box below for more info (you don't need to know how these work to use this function)
consteval auto compileTimeEval(auto value)
{
    return value;
}

constexpr int greater(int x, int y) // function is constexpr
{
    return (x &gt; y ? x : y);
}

int main()
{
    std::cout &lt;&lt; greater(5, 6) &lt;&lt; '\n';                  // may or may not execute at compile-time
    std::cout &lt;&lt; compileTimeEval(greater(5, 6)) &lt;&lt; '\n'; // will execute at compile-time

    int x { 5 };
    std::cout &lt;&lt; greater(x, 6) &lt;&lt; '\n';                  // we can still call the constexpr version at runtime if we wish

    return 0;
}</code></pre>
<p>This works because consteval functions require constant expressions as arguments -- therefore, if we use the return value of a constexpr function as an argument to a consteval function, the constexpr function must be evaluated at compile-time!  The consteval function just returns this argument as its own return value, so the caller can still use it.</p>
<p>Note that the consteval function returns by value.  While this might be inefficient to do at runtime (if the value was some type that is expensive to copy, e.g. std::string), in a compile-time context, it doesn&#8217;t matter because the entire call to the consteval function will simply be replaced with the calculated return value.</p>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">Related content</p>
<p>We cover <code>auto</code> return types in lesson <a href="https://www.learncpp.com/cpp-tutorial/type-deduction-for-functions/">10.9 -- Type deduction for functions</a>.<br />
We cover abbreviated function templates (<code>auto</code> parameters) in lesson <a href="https://www.learncpp.com/cpp-tutorial/function-templates-with-multiple-template-types/">11.8 -- Function templates with multiple template types</a>.
</div>
<p class="cpp-section">Determining if a constexpr function call is evaluating at compile-time or runtime</p>
<p>C++ does not currently provide any reliable mechanisms to do this.</p>
<p class="cpp-section cpp-topline" style="clear: both">What about <code>std::is_constant_evaluated</code> or <code>if consteval</code>? <span class="cpp-section-pill cpp-section-advanced">Advanced</span></p>
<p>Neither of these capabilities tell you whether a function call is evaluating at compile-time or runtime.</p>
<p><code>std::is_constant_evaluated()</code> (defined in the &lt;type_traits&gt; header) returns a <code>bool</code> indicating whether the current function is executing in a constant-evaluated context.  A <strong>constant-evaluated context</strong> (also called a <strong>constant context</strong>) is defined as one in which a constant expression is required (such as the initialization of a constexpr variable).  So in cases where the compiler is required to evaluate a constant expression at compile-time <code>std::is_constant_evaluated()</code> will <code>true</code> as expected.</p>
<p>This is intended to allow you to do something like this:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;type_traits&gt; // for std::is_constant_evaluated()

constexpr int someFunction()
{
    if (std::is_constant_evaluated()) // if evaluating in constant context
        doSomething();
    else
        doSomethingElse();
}</code></pre>
<p>However, the compiler may also choose to evaluate a constexpr function at compile-time in a context that does not require a constant expression.  In such cases, <code>std::is_constant_evaluated()</code> will return <code>false</code> even though the function did evaluate at compile-time.  So <code>std::is_constant_evaluated()</code> really means &#8220;the compiler is being forced to evaluate this at compile-time&#8221;, not &#8220;this is evaluating at compile-time&#8221;.</p>
<div class="cpp-note cpp-lightbluebackground">
<p class="cpp-note-title cpp-bottomline">Key insight</p>
<p>While this may seem strange, there are several reasons for this:</p>
<ol start="1">
<li>As <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0595r2.html">the paper that proposed this feature</a> indicates, the standard doesn&#8217;t actually make a distinction between &#8220;compile time&#8221; and &#8220;runtime&#8221;.  Defining behavior involving that distinction would have been a larger change.
</li>
<li>Optimizations should not change the observable behavior of a program (unless explicitly allowed by the standard).  If <code>std::is_constant_evaluated()</code> were to return <code>true</code> when the function was evaluated at compile-time for any reason, then the optimizer deciding to evaluate a function at compile-time instead of runtime could potentially change the observable behavior of the function.  As a result, your program might behave very differently depending on what optimization level it was compiled with!
</li>
</ol>
<p>While this could be addressed in various ways, those involve adding additional complexity to the optimizer and/or limiting its ability to optimize certain cases.
</p></div>
<p>Introduced in C++23, <code>if consteval</code> is a replacement for <code>if (std::is_constant_evaluated())</code> that provides a nicer syntax and fixes some other issues.  However, it evaluates the same way.</p>
<div class="prevnext"><div class="prevnext-inline">
	<a class="nav-link" href="https://www.learncpp.com/cpp-tutorial/constexpr-functions-part-4/">
 <div class="nav-button nav-button-next">
    <div class="nav-button-icon"><i class="fa fa-chevron-circle-right" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Next lesson</div>
      <div class="nav-button-lesson">
        <span class="nav-button-lesson-number">F.4</span>Constexpr functions (part 4)
      </div>
    </div>
  </div></a>
  	<a class="nav-link" href="/">
  <div class="nav-button nav-button-index">
    <div class="nav-button-icon"><i class="fa fa-home" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Back to table of contents</div>
    </div>
</div></a>
  	<a class="nav-link" href="https://www.learncpp.com/cpp-tutorial/constexpr-functions-part-2/">
  <div class="nav-button nav-button-prev">
    <div class="nav-button-icon"><i class="fa fa-chevron-circle-left" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Previous lesson</div>
      <div class="nav-button-lesson">
        <span class="nav-button-lesson-number">F.2</span>Constexpr functions (part 2)
      </div>
    </div>
  </div></a>
  </div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.learncpp.com/cpp-tutorial/constexpr-functions-part-3-and-consteval/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>F.2 &#8212; Constexpr functions (part 2)</title>
		<link>https://www.learncpp.com/cpp-tutorial/constexpr-functions-part-2/</link>
					<comments>https://www.learncpp.com/cpp-tutorial/constexpr-functions-part-2/#comments</comments>
		
		<dc:creator><![CDATA[Alex]]></dc:creator>
		<pubDate>Wed, 27 Nov 2024 00:16:29 +0000</pubDate>
				<category><![CDATA[C++ Tutorial]]></category>
		<guid isPermaLink="false">https://www.learncpp.com/?p=17890</guid>

					<description><![CDATA[Constexpr function calls in non-required constant expressions You might expect that a constexpr function would evaluate at compile-time whenever possible, but unfortunately this is not the case. In lesson , we noted that in contexts that do not require a constant expression, the compiler may choose whether to evaluate a &#8230;]]></description>
										<content:encoded><![CDATA[<p class="cpp-section">Constexpr function calls in non-required constant expressions</p>
<p>You might expect that a constexpr function would evaluate at compile-time whenever possible, but unfortunately this is not the case.</p>
<p>In lesson <a href="https://www.learncpp.com/cpp-tutorial/constant-expressions/">5.5 -- Constant expressions</a>, we noted that in contexts that do not <em>require</em> a constant expression, the compiler may choose whether to evaluate a constant expression at either compile-time or at runtime.  Accordingly, any constexpr function call that is part of a non-required constant expression may be evaluated at either compile-time or runtime.</p>
<p>For example:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

constexpr int getValue(int x)
{
    return x;
}

int main()
{
    int x { getValue(5) }; // may evaluate at runtime or compile-time
    
    return 0;
}</code></pre>
<p>In the above example, because <code>getValue()</code> is constexpr, the call <code>getValue(5)</code> is a constant expression.  However, because variable <code>x</code> is not constexpr, it does not require a constant expression initializer.  So even though we&#8217;ve provided a constant expression initializer, the compiler is free to choose whether <code>getValue(5)</code> evaluates at runtime or compile-time.</p>
<div class="cpp-note cpp-lightbluebackground">
<p class="cpp-note-title cpp-bottomline">Key insight</p>
<p>Compile-time evaluation of constexpr functions is only guaranteed when a constant expression is required.
</p></div>
<p class="cpp-section cpp-topline" style="clear: both">Diagnosis of constexpr functions in required constant expressions</p>
<p>The compiler is <em>not</em> required to determine whether a constexpr function is evaluatable at compile-time until it is actually evaluated at compile-time.  It is fairly easy to write a constexpr function that compiles successfully for runtime use, but then fails to compile when evaluated at compile-time.</p>
<p>As a silly example of this:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

int getValue(int x)
{
    return x;
}

// This function can be evaluated at runtime
// When evaluated at compile-time, the function will produce a compilation error
// because the call to getValue(x) cannot be resolved at compile-time
constexpr int foo(int x)
{
    if (x &lt; 0) return 0; // needed prior to adoption of P2448R1 in C++23 (see note below)
    return getValue(x);  // call to non-constexpr function here
}

int main()
{
    int x { foo(5) };           // okay: will evaluate at runtime
    constexpr int y { foo(5) }; // compile error: foo(5) can't evaluate at compile-time

    return 0;
}</code></pre>
<p>In the above example, when <code>foo(5)</code> is used as an initializer for non-constexpr variable <code>x</code>, it will be evaluated at runtime.  This works fine, and returns the value <code>5</code>.</p>
<p>However, when <code>foo(5)</code>, is used as an initializer for constexpr variable <code>y</code>, it must be evaluated at compile-time.  At that point, the compiler will determine that the call to <code>foo(5)</code> can&#8217;t be evaluated at compile-time, as <code>getValue()</code> is not a constexpr function.</p>
<p>Therefore, when writing a constexpr function, always explicitly test that it compiles when evaluated at compile-time (by calling it in a context where a constant expression is required, such as in the initialization of a constexpr variable).</p>
<div class="cpp-note cpp-lightgreenbackground">
<p class="cpp-note-title cpp-bottomline">Best practice</p>
<p>All constexpr functions should be evaluatable at compile-time, as they will be required to do so in contexts that require a constant expression.</p>
<p>Always test your constexpr functions in a context that requires a constant expression, as the constexpr function may work when evaluated at runtime but fail when evaluated at compile-time.
</p></div>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">For advanced readers</p>
<p>Prior to C++23, if no argument values exist that would allow a constexpr function to be evaluated at compile-time, the program is ill-formed (no diagnostic required).  Without the line <code>if (x &lt; 0) return 0</code>, the above example would contain no set of arguments that allow the function to be evaluatable at compile-time, making the program ill-formed.  Given that no diagnostic is required, the compiler may not enforce this.</p>
<p>This requirement was revoked in C++23 (<a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2448r1.html">P2448R1</a>).
</div>
<p class="cpp-section cpp-topline" style="clear: both">Constexpr/consteval function parameters are not constexpr</p>
<p>The parameters of a constexpr function are not implicitly constexpr, nor may they be declared as <code>constexpr</code>.</p>
<div class="cpp-note cpp-lightbluebackground">
<p class="cpp-note-title cpp-bottomline">Key insight</p>
<p>A constexpr function parameter would imply the function could only be called with a constexpr argument.  But this is not the case -- constexpr functions can be called with non-constexpr arguments when the function is evaluated at runtime.
</p></div>
<p>Because such parameters are not constexpr, they cannot be used in constant expressions within the function.</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">consteval int goo(int c)    // c is not constexpr, and cannot be used in constant expressions
{
    return c;
}

constexpr int foo(int b)    // b is not constexpr, and cannot be used in constant expressions
{
    constexpr int b2 { b }; // compile error: constexpr variable requires constant expression initializer

    return goo(b);          // compile error: consteval function call requires constant expression argument
}

int main()
{
    constexpr int a { 5 };

    std::cout &lt;&lt; foo(a); // okay: constant expression a can be used as argument to constexpr function foo()
    
    return 0;
}</code></pre>
<p>In the above example, function parameter <code>b</code> is not constexpr (even though argument <code>a</code> is a constant expression).  This means <code>b</code> cannot be used anywhere a constant expression is required, such as the the initializer for a constexpr variable (e.g. <code>b2</code>) or in a call to a consteval function (<code>goo(b)</code>).</p>
<p>The parameters of constexpr functions may be declared as <code>const</code>, in which case they are treated as runtime constants.</p>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">Related content</p>
<p>If you need parameters that are constant expressions, see <a href="https://www.learncpp.com/cpp-tutorial/non-type-template-parameters/">11.9 -- Non-type template parameters</a>.
</p></div>
<p class="cpp-section cpp-topline" style="clear: both">Constexpr functions are implicitly inline</p>
<p>When a constexpr function is evaluated at compile-time, the compiler must be able to see the full definition of the constexpr function prior to such function calls (so it can perform the evaluation itself).  A forward declaration will not suffice in this case, even if the actual function definition appears later in the same compilation unit.</p>
<p>This means that a constexpr function called in multiple files needs to have its definition included into each translation unit -- which would normally be a violation of the one-definition rule.  To avoid such problems, constexpr functions are implicitly inline, which makes them exempt from the one-definition rule.</p>
<p>As a result, constexpr functions are often defined in header files, so they can be #included into any .cpp file that requires the full definition.</p>
<div class="cpp-note cpp-lightpurplebackground">
<p class="cpp-note-title cpp-bottomline">Rule</p>
<p>The compiler must be able to see the full definition of a constexpr (or consteval) function, not just a forward declaration.
</p></div>
<div class="cpp-note cpp-lightgreenbackground">
<p class="cpp-note-title cpp-bottomline">Best practice</p>
<p>Constexpr/consteval functions used in a single source file (.cpp) should be defined in the source file above where they are used.</p>
<p>Constexpr/consteval functions used in multiple source files should be defined in a header file so they can be included into each source file.
</p></div>
<p>For constexpr function calls that are only evaluated at runtime, a forward declaration is sufficient to satisfy the compiler.  This means you can use a forward declaration to call a constexpr function defined in another translation unit, but only if you invoke it in a context that does not require compile-time evaluation.</p>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">For advanced readers</p>
<p>Per <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2166">CWG2166</a>, the actual requirement for the forward declaration of constexpr functions that are evaluated at compile-time is that &#8220;the constexpr function must be defined prior to the outermost evaluation that eventually results in the invocation&#8221;.  Therefore, this is allowed:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

constexpr int foo(int);

constexpr int goo(int c)
{
	return foo(c);   // note that foo is not defined yet
}

constexpr int foo(int b) // okay because foo is still defined before any calls to goo
{
	return b;
}

int main()
{
	 constexpr int a{ goo(5) }; // this is the outermost invocation

	return 0;
}</code></pre>
<p>The intent here is to allow for mutually recursive constexpr functions (where two constexpr functions call each other), which would not be possible otherwise.
</p></div>
<p class="cpp-section cpp-topline" style="clear: both">Recap</p>
<p>Marking a function as <code>constexpr</code> means it can be used in a constant expression.  It does not mean &#8220;will evaluate at compile-time&#8221;.</p>
<p>A constant expression (which may contain constexpr function calls) is only required to evaluate at compile-time in contexts where a constant expression is required.</p>
<p>In contexts that do not require a constant expression, the compiler may choose whether to evaluate a constant expression (which may contain constexpr function calls) at compile-time or at runtime.</p>
<p>A runtime (non-constant) expression (which may contain constexpr function calls or non-constexpr function calls) will evaluate at runtime.</p>
<p class="cpp-section cpp-topline" style="clear: both">Another example</p>
<p>Let&#8217;s do another examine to explore how a constexpr function is required or likely to evaluate further:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

constexpr int greater(int x, int y)
{
    return (x &gt; y ? x : y);
}

int main()
{
    constexpr int g { greater(5, 6) };              // case 1: always evaluated at compile-time
    std::cout &lt;&lt; g &lt;&lt; " is greater!\n";

    std::cout &lt;&lt; greater(5, 6) &lt;&lt; " is greater!\n"; // case 2: may be evaluated at either runtime or compile-time

    int x{ 5 }; // not constexpr but value is known at compile-time
    std::cout &lt;&lt; greater(x, 6) &lt;&lt; " is greater!\n"; // case 3: likely evaluated at runtime

    std::cin &gt;&gt; x;
    std::cout &lt;&lt; greater(x, 6) &lt;&lt; " is greater!\n"; // case 4: always evaluated at runtime

    return 0;
}</code></pre>
<p>In case 1, we&#8217;re calling <code>greater()</code> in a context that requires a constant expression.  Thus <code>greater()</code> must be evaluated at compile-time.</p>
<p>In case 2, the <code>greater()</code> function is being called in a context that does not require a constant expression, as output statements must execute at runtime.  However, since the arguments are constant expressions, the function is eligible to be evaluated at compile-time.  Thus the compiler is free to choose whether this call to <code>greater()</code> will be evaluated at compile-time or runtime.</p>
<p>In case 3, we&#8217;re calling <code>greater()</code> with one argument that is not a constant expression.  So this will typically execute at runtime.</p>
<p>However, this argument has a value that is known at compile-time.  Under the as-if rule, the compiler could decide to treat the evaluation of <code>x</code> as a constant expression, and evaluate this call to <code>greater()</code> at compile-time.  But more likely, it will evaluate it at runtime.</p>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">Related content</p>
<p>We cover the as-if rule in lesson <a href="https://www.learncpp.com/cpp-tutorial/constant-expressions/">5.5 -- Constant expressions</a>.</p>
<p>Note that even non-constexpr functions could be evaluated at compile-time under the as-if rule!
</p></div>
<p>In case 4, the value of argument <code>x</code> can&#8217;t be known at compile-time, so this call to <code>greater()</code> will always evaluate at runtime.</p>
<div class="cpp-note cpp-lightbluebackground">
<p class="cpp-note-title cpp-bottomline">Key insight</p>
<p>Put another way, we can categorize the likelihood that a function will actually be evaluated at compile-time as follows:</p>
<p>Always (required by the standard):</p>
<ul>
<li>Constexpr function is called where constant expression is required.
</li>
<li>Constexpr function is called from other function being evaluated at compile-time.
</li>
</ul>
<p>Probably (there&#8217;s little reason not to):</p>
<ul>
<li>Constexpr function is called where constant expression isn&#8217;t required, all arguments are constant expressions.
</li>
</ul>
<p>Possibly (if optimized under the as-if rule):</p>
<ul>
<li>Constexpr function is called where constant expression isn&#8217;t required, some arguments are not constant expressions but their values are known at compile-time.
</li>
<li>Non-constexpr function capable of being evaluated at compile-time, all arguments are constant expressions.
</li>
</ul>
<p>Never (not possible):</p>
<ul>
<li>Constexpr function is called where constant expression isn&#8217;t required, some arguments have values that are not known at compile-time.
</li>
</ul>
</div>
<p>Note that your compiler&#8217;s optimization level setting may have an impact on whether it decides to evaluate a function at compile-time or runtime.  This also means that your compiler may make different choices for debug vs. release builds (as debug builds typically have optimizations turned off).</p>
<p>For example, both gcc and Clang will not compile-time evaluate a constexpr function called where a constant expression isn&#8217;t required unless the compiler told to optimize the code (e.g. using the <code>-O2</code> compiler option).</p>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">For advanced readers</p>
<p>The compiler might also choose to inline a function call, or even optimize a function call away entirely.  Both of these can affect when (or if) the content of the function call are evaluated.
</p></div>
<div class="prevnext"><div class="prevnext-inline">
	<a class="nav-link" href="https://www.learncpp.com/cpp-tutorial/constexpr-functions-part-3-and-consteval/">
 <div class="nav-button nav-button-next">
    <div class="nav-button-icon"><i class="fa fa-chevron-circle-right" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Next lesson</div>
      <div class="nav-button-lesson">
        <span class="nav-button-lesson-number">F.3</span>Constexpr functions (part 3) and consteval
      </div>
    </div>
  </div></a>
  	<a class="nav-link" href="/">
  <div class="nav-button nav-button-index">
    <div class="nav-button-icon"><i class="fa fa-home" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Back to table of contents</div>
    </div>
</div></a>
  	<a class="nav-link" href="https://www.learncpp.com/cpp-tutorial/constexpr-functions/">
  <div class="nav-button nav-button-prev">
    <div class="nav-button-icon"><i class="fa fa-chevron-circle-left" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Previous lesson</div>
      <div class="nav-button-lesson">
        <span class="nav-button-lesson-number">F.1</span>Constexpr functions
      </div>
    </div>
  </div></a>
  </div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.learncpp.com/cpp-tutorial/constexpr-functions-part-2/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
		<item>
		<title>5.4 &#8212; The as-if rule and compile-time optimization</title>
		<link>https://www.learncpp.com/cpp-tutorial/the-as-if-rule-and-compile-time-optimization/</link>
					<comments>https://www.learncpp.com/cpp-tutorial/the-as-if-rule-and-compile-time-optimization/#comments</comments>
		
		<dc:creator><![CDATA[Alex]]></dc:creator>
		<pubDate>Tue, 22 Oct 2024 19:48:59 +0000</pubDate>
				<category><![CDATA[C++ Tutorial]]></category>
		<guid isPermaLink="false">https://www.learncpp.com/?p=17475</guid>

					<description><![CDATA[Introduction to optimization In programming, optimization is the process of modifying software to make it work more efficiently (e.g. to run faster, or use fewer resources). Optimization can have a huge impact on the overall performance level of an application. Some types of optimization are typically done by hand. A &#8230;]]></description>
										<content:encoded><![CDATA[<p class="cpp-section">Introduction to optimization</p>
<p>In programming, <strong>optimization</strong> is the process of modifying software to make it work more efficiently (e.g. to run faster, or use fewer resources).  Optimization can have a huge impact on the overall performance level of an application.</p>
<p>Some types of optimization are typically done by hand.  A program called a <strong>profiler</strong> can be used to see how long various parts of the program are taking to run, and which are impacting overall performance.  The programmer can then look for ways to alleviate those performance issues.  Because hand-optimization is slow, programmers typically focuses on making high-level improvements that will have a large impact (such as choosing more performant algorithms, optimizing data storage and access, reducing resource utilization, parallelizing tasks, etc&#8230;)</p>
<p>Other kinds of optimization can be performed automatically.  A program that optimizes another program is called an <strong>optimizer</strong>.  Optimizers typically work at a low-level, looking for ways to improve statements or expressions by rewriting, reordering, or eliminating them.  For example, when you write <code>i = i * 2;</code>, the optimizer might rewrite this as <code> i *= 2;</code>, <code>i += i;</code>, or <code>i &lt;&lt;= 1;</code>.  For integral values, all of these produce the same result, but one might be faster than the others on a given architecture.  A programmer would probably not know which is the most performant choice (and the answer might vary based on architecture), but an optimizer for a given system would.  Individual low-level optimizations may only yield small performance gains, but their cumulative effect can result in a significant performance improvement overall.</p>
<p>Modern C++ compilers are optimizing compilers, meaning they are capable of automatically optimizing your programs as part of the compilation process.  Just like the preprocessor, these optimizations do not modify your source code files -- rather, they are applied transparently as part of the compilation process.</p>
<div class="cpp-note cpp-lightbluebackground">
<p class="cpp-note-title cpp-bottomline">Key insight</p>
<p>Optimizing compilers allow programmers to focus on writing code that is readable and maintainable without sacrificing performance.
</p></div>
<p>Because optimization involves some tradeoffs (we&#8217;ll discuss this at the bottom of the lesson), compilers typically support multiple optimization levels that determine whether they optimize, how aggressively they optimize, and what kind of optimizations they prioritize (e.g. speed vs size).</p>
<p>Most compilers default to no optimization, so if you&#8217;re using a command-line compiler, you&#8217;ll need to enable optimization yourself.  If you&#8217;re using an IDE, the IDE will likely automatically configure release builds to enable optimization and debug builds to disable optimization.</p>
<div class="cpp-note cpp-lightyellowbackground">
<p class="cpp-note-title cpp-bottomline">For gcc and Clang users</p>
<p>See <a href="https://www.learncpp.com/cpp-tutorial/configuring-your-compiler-build-configurations/">0.9 -- Configuring your compiler: Build configurations</a> for information on how to enable optimization.
</p></div>
<p class="cpp-section">The as-if rule</p>
<p>In C++, compilers are given a lot of leeway to optimize programs.  The <strong>as-if rule</strong> says that the compiler can modify a program however it likes in order to produce more optimized code, so long as those modifications do not affect a program&#8217;s &#8220;observable behavior&#8221;.</p>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">For advanced readers</p>
<p>There is one notable exception to the as-if rule: unnecessary calls to a copy (or move) constructor can be elided (omitted) even if those constructors have observable behavior.  We cover this topic in lesson <a href="https://www.learncpp.com/cpp-tutorial/class-initialization-and-copy-elision/">14.15 -- Class initialization and copy elision</a>.
</p></div>
<p>Modern compilers employ a variety of different techniques in order to optimize a program effectively.  Which techniques can be applied depends on the program and the quality of the compiler and optimizer.</p>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">Related content</p>
<p><a href="https://en.wikipedia.org/wiki/Optimizing_compiler#Specific_techniques">Wikipedia</a> has list of specific techniques that compilers use.
</div>
<p class="cpp-section cpp-topline" style="clear: both">An optimization opportunity</p>
<p>Consider the following short program:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

int main()
{
	int x { 3 + 4 };
	std::cout &lt;&lt; x &lt;&lt; '\n';

	return 0;
}</code></pre>
<p>The output is straightforward:</p>
<pre>
7
</pre>
<p>However, there&#8217;s an interesting optimization possibility hidden within.</p>
<p>If this program were compiled exactly as it was written (with no optimizations), the compiler would generate an executable that calculates the result of <code>3 + 4</code> at runtime (when the program is run).  If the program were executed a million times, <code>3 + 4</code> would be evaluated a million times, and the resulting value of <code>7</code> produced a million times.</p>
<p>Because the result of <code>3 + 4</code> never changes (it is always <code>7</code>), re-calculating this result every time the program is run is wasteful.</p>
<p class="cpp-section cpp-topline" style="clear: both">Compile-time evaluation</p>
<p>Modern C++ compilers are capable of fully or partially evaluating certain expressions at compile-time (rather than at runtime).  When the compiler fully or partially evaluates an expression at compile-time, this is called <strong>compile-time evaluation</strong>.</p>
<div class="cpp-note cpp-lightbluebackground">
<p class="cpp-note-title cpp-bottomline">Key insight</p>
<p>Compile-time evaluation allows the compiler to do work at compile-time that would otherwise be done at runtime.  Because such expressions no longer need to be evaluated at runtime, the resulting executables are faster and smaller (at the cost of slightly slower compilation times).
</p></div>
<p>For illustrative purposes, in this lesson we will look at some simple optimization techniques that make use of compile-time evaluation.  Then, we&#8217;ll continue our discussion of compile-time evaluation in subsequent lessons.</p>
<p class="cpp-section cpp-topline" style="clear: both">Constant folding</p>
<p>One of the original forms of compile-time evaluation is called &#8220;constant folding&#8221;.  <strong>Constant folding</strong> is an optimization technique where the compiler replaces expressions that have literal operands with the result of the expression.  Using constant folding, the compiler would recognize that the expression <code>3 + 4</code> has constant operands, and then replace the expression with the result <code>7</code>.</p>
<p>The result would be equivalent to the following:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

int main()
{
	int x { 7 };
	std::cout &lt;&lt; x &lt;&lt; '\n';

	return 0;
}</code></pre>
<p>This program produces the same output (<code>7</code>) as the prior version, but the resulting executable no longer needs to spend CPU cycles calculating <code>3 + 4</code> at runtime!  </p>
<p>Constant folding can also be applied to subexpressions, even when the full expression must execute at runtime.</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

int main()
{
	std::cout &lt;&lt; 3 + 4 &lt;&lt; '\n';

	return 0;
}</code></pre>
<p>In the above example, <code>3 + 4</code> is a subexpression of the full expression <code>std::cout &lt;&lt; 3 + 4 &lt;&lt; '\n';</code>.  The compiler can optimize this to <code>std::cout &lt;&lt; 7 &lt;&lt; '\n';</code>.</p>
<p class="cpp-section cpp-topline" style="clear: both">Constant propagation</p>
<p>The following program contains another optimization opportunity:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

int main()
{
	int x { 7 };
	std::cout &lt;&lt; x &lt;&lt; '\n';

	return 0;
}</code></pre>
<p>When <code>x</code> is initialized, the value <code>7</code> will be stored in the memory allocated for <code>x</code>.  Then on the next line, the program will go out to memory again to fetch the value <code>7</code> so it can be printed.  This requires two memory access operations (one to store the value, and one to fetch it).</p>
<p><strong>Constant propagation</strong> is an optimization technique where the compiler replaces variables known to have constant values with their values.  Using constant propagation, the compiler would realize that <code>x</code> always has the constant value <code>7</code>, and replace any use of variable <code>x</code> with the value <code>7</code>.</p>
<p>The result would be equivalent to the following:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

int main()
{
	int x { 7 };
	std::cout &lt;&lt; 7 &lt;&lt; '\n';

	return 0;
}</code></pre>
<p>This removes the need for the program to go out to memory to fetch the value of <code>x</code>.</p>
<p>Constant propagation may produce a result that can then be optimized by constant folding:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

int main()
{
	int x { 7 };
	int y { 3 };
	std::cout &lt;&lt; x + y &lt;&lt; '\n';

	return 0;
}</code></pre>
<p>In this example, constant propagation would transform <code>x + y</code> into <code>7 + 3</code>, which can then be constant folded into the value <code>10</code>.</p>
<p class="cpp-section cpp-topline" style="clear: both">Dead code elimination</p>
<p><strong>Dead code elimination</strong> is an optimization technique where the compiler removes code that may be executed but has no effect on the program&#8217;s behavior.</p>
<p>Back to a prior example:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

int main()
{
	int x { 7 };
	std::cout &lt;&lt; 7 &lt;&lt; '\n';

	return 0;
}</code></pre>
<p>In this program, variable <code>x</code> is defined and initialized, but it is never used anywhere, so it has no effect on the program&#8217;s behavior.  Dead code elimination would remove the definition of <code>x</code>.</p>
<p>The result would be equivalent to the following:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

int main()
{
	std::cout &lt;&lt; 7 &lt;&lt; '\n';

	return 0;
}</code></pre>
<p>When a variable is removed from a program because it is no longer needed, we say the variable has been <strong>optimized out</strong> (or <strong>optimized away</strong>).</p>
<p>Compared to the original version, this optimized version no longer requires runtime calculation expression <code>3 + 4</code>, nor does it require two memory access operations (one to initialize variable <code>x</code> and one to read the value from <code>x</code>).  This means the program will be both smaller and faster.</p>
<p class="cpp-section cpp-topline" style="clear: both">Const variables are easier to optimize</p>
<p>In some cases, there are simple things we can do to help the compiler optimize more effectively.</p>
<p>Constant propagation can be challenging for the compiler.  In the section on constant propagation, we offered this example:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

int main()
{
	int x { 7 };
	std::cout &lt;&lt; x &lt;&lt; '\n';

	return 0;
}</code></pre>
<p>Since <code>x</code> is defined as a non-const variable, in order to apply this optimization, the compiler must realize that the value of <code>x</code> actually doesn&#8217;t change (even though it could).  Whether the compiler is capable of doing so comes down to how complex the program is and how sophisticated the compiler&#8217;s optimization routines are.</p>
<p>We can help the compiler optimize more effectively by using constant variables wherever possible.  For example:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

int main()
{
	const int x { 7 }; // x is now const
	std::cout &lt;&lt; x &lt;&lt; '\n';

	return 0;
}</code></pre>
<p>Because <code>x</code> is now const, the compiler has a guarantee that <code>x</code> can&#8217;t be changed after initialization.  This makes it more likely the compiler will apply constant propagation, and then optimize the variable out entirely.</p>
<div class="cpp-note cpp-lightbluebackground">
<p class="cpp-note-title cpp-bottomline">Key insight</p>
<p>Using const variables can help the compiler optimize more effectively.
</p></div>
<p class="cpp-section cpp-topline" style="clear: both">Optimization can make programs harder to debug</p>
<p>If optimization makes our programs faster, why isn&#8217;t it turned on by default?</p>
<p>When the compiler optimizes a program, the result is that variables, expressions, statements, and function calls may be rearranged, modified, replaced, or removed entirely.  Such changes can make it hard to debug a program effectively.</p>
<p>At runtime, it can be hard to debug compiled code that no longer correlates very well with the original source code.  For example, if you try to watch a variable that has been optimized out, the debugger won&#8217;t be able to locate the variable.  If you try to step into a function that has been optimized away, the debugger will simply skip over it.  So if you are debugging your code and the debugger is behaving strangely, this is the most likely reason.</p>
<p>At compile-time, we have little visibility and few tools to help us understand what the compiler is even doing.  If a variable or expression is replaced with a value, and that value is wrong, how do we even go about debugging the issue?  This is an ongoing challenge.</p>
<p>To help minimize such issues, debug builds will typically leave optimizations turned off, so that the compiled code will more closely match the source code.</p>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">Author&#8217;s note</p>
<p>Compile-time debugging is an underdeveloped area.  As of C++23, there are a number of papers under consideration for future language standards (such as <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2758r1.html">this one</a>) that (if approved) will add capabilities to the language that will help.
</div>
<p class="cpp-section cpp-topline" style="clear: both">Nomenclature: Compile-time constants vs runtime constants</p>
<p>Constants in C++ are sometimes divided into two informal categories.</p>
<p>A <strong>compile-time constant</strong> is a constant whose value is known at compile-time.  Examples include:</p>
<ul>
<li>Literals.
</li>
<li>Constant objects whose initializers are compile-time constants.
</li>
</ul>
<p>A <strong>runtime constant</strong> is a constant whose value is determined in a runtime context.  Examples include:</p>
<ul>
<li>Constant function parameters.
</li>
<li>Constant objects whose initializers are non-constants or runtime constants.
</li>
</ul>
<p>For example:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

int five()
{
    return 5;
}

int pass(const int x) // x is a runtime constant
{
    return x;
}

int main()
{
    // The following are non-constants:
    [[maybe_unused]] int a { 5 };

    // The following are compile-time constants:
    [[maybe_unused]] const int b { 5 };
    [[maybe_unused]] const double c { 1.2 };
    [[maybe_unused]] const int d { b };       // b is a compile-time constant

    // The following are runtime constants:
    [[maybe_unused]] const int e { a };       // a is non-const
    [[maybe_unused]] const int f { e };       // e is a runtime constant
    [[maybe_unused]] const int g { five() };  // return value isn't known until runtime
    [[maybe_unused]] const int h { pass(5) }; // return value isn't known until runtime

    return 0;
}</code></pre>
<p>Although you will encounter these terms out in the wild, in C++ these definitions are not all that useful:</p>
<ul>
<li>Some runtime constants (and even non-constants) can be evaluated at compile-time for optimization purposes (under the as-if rule).
</li>
<li>Some compile-time constants (e.g. <code>const double d { 1.2 };</code>) cannot be used in compile-time features (as defined by the language standard).  We&#8217;ll discuss this more in lesson <a href="https://www.learncpp.com/cpp-tutorial/constant-expressions/">5.5 -- Constant expressions</a>.
</li>
</ul>
<p>For this reason, we recommend avoiding these terms.  We&#8217;ll discuss the nomenclature that you should use instead in the next lesson.</p>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">Author&#8217;s note</p>
<p>We are in the process of phasing these terms out of future articles.
</p></div>
<div class="prevnext"><div class="prevnext-inline">
	<a class="nav-link" href="https://www.learncpp.com/cpp-tutorial/constant-expressions/">
 <div class="nav-button nav-button-next">
    <div class="nav-button-icon"><i class="fa fa-chevron-circle-right" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Next lesson</div>
      <div class="nav-button-lesson">
        <span class="nav-button-lesson-number">5.5</span>Constant expressions
      </div>
    </div>
  </div></a>
  	<a class="nav-link" href="/">
  <div class="nav-button nav-button-index">
    <div class="nav-button-icon"><i class="fa fa-home" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Back to table of contents</div>
    </div>
</div></a>
  	<a class="nav-link" href="https://www.learncpp.com/cpp-tutorial/numeral-systems-decimal-binary-hexadecimal-and-octal/">
  <div class="nav-button nav-button-prev">
    <div class="nav-button-icon"><i class="fa fa-chevron-circle-left" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Previous lesson</div>
      <div class="nav-button-lesson">
        <span class="nav-button-lesson-number">5.3</span>Numeral systems (decimal, binary, hexadecimal, and octal)
      </div>
    </div>
  </div></a>
  </div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.learncpp.com/cpp-tutorial/the-as-if-rule-and-compile-time-optimization/feed/</wfw:commentRss>
			<slash:comments>14</slash:comments>
		
		
			</item>
		<item>
		<title>11.10 &#8212; Using function templates in multiple files</title>
		<link>https://www.learncpp.com/cpp-tutorial/using-function-templates-in-multiple-files/</link>
					<comments>https://www.learncpp.com/cpp-tutorial/using-function-templates-in-multiple-files/#comments</comments>
		
		<dc:creator><![CDATA[Alex]]></dc:creator>
		<pubDate>Tue, 11 Jun 2024 18:06:42 +0000</pubDate>
				<category><![CDATA[C++ Tutorial]]></category>
		<guid isPermaLink="false">https://www.learncpp.com/?p=17180</guid>

					<description><![CDATA[Consider the following program, which doesn&#8217;t work correctly: main.cpp: #include &#60;iostream&#62; template &#60;typename T&#62; T addOne(T x); // function template forward declaration int main() { std::cout &#60;&#60; addOne(1) &#60;&#60; '\n'; std::cout &#60;&#60; addOne(2.3) &#60;&#60; '\n'; return 0; } add.cpp: template &#60;typename T&#62; T addOne(T x) // function template definition { &#8230;]]></description>
										<content:encoded><![CDATA[<p>Consider the following program, which doesn&#8217;t work correctly:</p>
<p>main.cpp:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

template &lt;typename T&gt;
T addOne(T x); // function template forward declaration

int main()
{
    std::cout &lt;&lt; addOne(1) &lt;&lt; '\n';
    std::cout &lt;&lt; addOne(2.3) &lt;&lt; '\n';

    return 0;
}</code></pre>
<p>add.cpp:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">template &lt;typename T&gt;
T addOne(T x) // function template definition
{
    return x + 1;
}</code></pre>
<p>If <code>addOne</code> were a non-template function, this program would work fine: In <em>main.cpp</em>, the compiler would be satisfied with the forward declaration of <code>addOne</code>, and the linker would connect the call to <code>addOne()</code> in <em>main.cpp</em> to the function definition in <em>add.cpp</em>.</p>
<p>But because <code>addOne</code> is a template, this program doesn&#8217;t work, and we get a linker error:</p>
<pre>
1&gt;Project6.obj : error LNK2019: unresolved external symbol "int __cdecl addOne&lt;int&gt;(int)" (??$addOne@H@@YAHH@Z) referenced in function _main
1&gt;Project6.obj : error LNK2019: unresolved external symbol "double __cdecl addOne&lt;double&gt;(double)" (??$addOne@N@@YANN@Z) referenced in function _main
</pre>
<p>In <em>main.cpp</em>, we call <code>addOne&lt;int&gt;</code> and <code>addOne&lt;double&gt;</code>.  However, since the compiler can&#8217;t see the definition for function template <code>addOne</code>, it can&#8217;t instantiate those functions inside <em>main.cpp</em>.  It does see the forward declaration for <code>addOne</code> though, and will assume those functions exist elsewhere and will be linked in later.</p>
<p>When the compiler goes to compile <em>add.cpp</em>, it will see the definition for function template <code>addOne</code>.  However, there are no uses of this template in <em>add.cpp</em>, so the compiler will not instantiate anything.  The end result is that the linker is unable to connect the calls to <code>addOne&lt;int&gt;</code> and <code>addOne&lt;double&gt;</code> in <em>main.cpp</em> to the actual functions, because those functions were never instantiated.</p>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">As an aside&#8230;</p>
<p>If <em>add.cpp</em> had instantiated those functions, the program would have compiled and linked just fine.  But such solutions are fragile and should be avoided: if the code in <em>add.cpp</em> was later changed so those functions are no longer instantiated, the program would again fail to link.  Or if <em>main.cpp</em> called a different version of <code>addOne</code> (such as <code>addOne&lt;float&gt;</code>) that was not instantiated in <em>add.cpp</em>, we run into the same problem.
</div>
<p>The most conventional way to address this issue is to put all your template code in a header (.h) file instead of a source (.cpp) file:</p>
<p>add.h:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#ifndef ADD_H
#define ADD_H

template &lt;typename T&gt;
T addOne(T x) // function template definition
{
    return x + 1;
}

#endif</code></pre>
<p>main.cpp:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include "add.h" // import the function template definition
#include &lt;iostream&gt;

int main()
{
    std::cout &lt;&lt; addOne(1) &lt;&lt; '\n';
    std::cout &lt;&lt; addOne(2.3) &lt;&lt; '\n';

    return 0;
}</code></pre>
<p>That way, any files that need access to the template can #include the relevant header, and the template definition will be copied by the preprocessor into the source file.  The compiler will then be able to instantiate any functions that are needed.</p>
<p>You may be wondering why this doesn&#8217;t cause a violation of the one-definition rule (ODR).  The ODR says that types, templates, inline functions, and inline variables are allowed to have identical definitions in different files.  So there is no problem if the template definition is copied into multiple files (as long as each definition is identical).</p>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">Related content</p>
<p>We covered the ODR in lesson <a href="https://www.learncpp.com/cpp-tutorial/forward-declarations/#ODR">2.7 -- Forward declarations and definitions</a>.
</p></div>
<p>But what about the instantiated functions themselves?  If a function is instantiated in multiple files, how does that not cause a violation of the ODR?  The answer is that functions implicitly instantiated from templates are implicitly inline.  And as you know, inline functions can be defined in multiple files, so long as the definition is identical in each.</p>
<div class="cpp-note cpp-lightbluebackground">
<p class="cpp-note-title cpp-bottomline">Key insight</p>
<p>Template definitions are exempt from the part of the one-definition rule that requires only one definition per program, so it is not a problem to have the same template definition #included into multiple source files.  And functions implicitly instantiated from function templates are implicitly inline, so they can be defined in multiple files, so long as each definition is identical.</p>
<p>The templates themselves are not inline, as the concept of inline only applies to variables and functions.
</p></div>
<p>Here&#8217;s another example of a function template being placed in a header file, so it can be included into multiple source files:</p>
<p>max.h:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#ifndef MAX_H
#define MAX_H

template &lt;typename T&gt;
T max(T x, T y)
{
    return (x &lt; y) ? y : x;
}

#endif</code></pre>
<p>foo.cpp:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include "max.h" // import template definition for max&lt;T&gt;(T, T)
#include &lt;iostream&gt;

void foo()
{
	std::cout &lt;&lt; max(3, 2) &lt;&lt; '\n';
}</code></pre>
<p>main.cpp:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include "max.h" // import template definition for max&lt;T&gt;(T, T)
#include &lt;iostream&gt;

void foo(); // forward declaration for function foo

int main()
{
    std::cout &lt;&lt; max(3, 5) &lt;&lt; '\n';
    foo();

    return 0;
}</code></pre>
<p>In the above example, both main.cpp and foo.cpp <code>#include "max.h"</code> so the code in both files can make use of the <code>max&lt;T&gt;(T, T)</code> function template.</p>
<div class="cpp-note cpp-lightgreenbackground">
<p class="cpp-note-title cpp-bottomline">Best practice</p>
<p>Templates that are needed in multiple files should be defined in a header file, and then #included wherever needed.  This allows the compiler to see the full template definition and instantiate the template when needed.
</p></div>
<div class="prevnext"><div class="prevnext-inline">
	<a class="nav-link" href="https://www.learncpp.com/cpp-tutorial/chapter-11-summary-and-quiz/">
 <div class="nav-button nav-button-next">
    <div class="nav-button-icon"><i class="fa fa-chevron-circle-right" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Next lesson</div>
      <div class="nav-button-lesson">
        <span class="nav-button-lesson-number">11.x</span>Chapter 11 summary and quiz
      </div>
    </div>
  </div></a>
  	<a class="nav-link" href="/">
  <div class="nav-button nav-button-index">
    <div class="nav-button-icon"><i class="fa fa-home" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Back to table of contents</div>
    </div>
</div></a>
  	<a class="nav-link" href="https://www.learncpp.com/cpp-tutorial/non-type-template-parameters/">
  <div class="nav-button nav-button-prev">
    <div class="nav-button-icon"><i class="fa fa-chevron-circle-left" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Previous lesson</div>
      <div class="nav-button-lesson">
        <span class="nav-button-lesson-number">11.9</span>Non-type template parameters
      </div>
    </div>
  </div></a>
  </div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.learncpp.com/cpp-tutorial/using-function-templates-in-multiple-files/feed/</wfw:commentRss>
			<slash:comments>19</slash:comments>
		
		
			</item>
		<item>
		<title>14.17 &#8212; Constexpr aggregates and classes</title>
		<link>https://www.learncpp.com/cpp-tutorial/constexpr-aggregates-and-classes/</link>
					<comments>https://www.learncpp.com/cpp-tutorial/constexpr-aggregates-and-classes/#comments</comments>
		
		<dc:creator><![CDATA[Alex]]></dc:creator>
		<pubDate>Wed, 22 May 2024 23:43:21 +0000</pubDate>
				<category><![CDATA[C++ Tutorial]]></category>
		<guid isPermaLink="false">https://www.learncpp.com/?p=17060</guid>

					<description><![CDATA[In lesson , we covered constexpr functions, which are functions that may be evaluated at either compile-time or runtime. For example: #include &#60;iostream&#62; constexpr int greater(int x, int y) { return (x &#62; y ? x : y); } int main() { std::cout &#60;&#60; greater(5, 6) &#60;&#60; '\n'; // greater(5, &#8230;]]></description>
										<content:encoded><![CDATA[<p>In lesson <a href="https://www.learncpp.com/cpp-tutorial/constexpr-functions/">F.1 -- Constexpr functions</a>, we covered constexpr functions, which are functions that may be evaluated at either compile-time or runtime.  For example:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

constexpr int greater(int x, int y)
{
    return (x &gt; y ? x : y);
}

int main()
{
    std::cout &lt;&lt; greater(5, 6) &lt;&lt; '\n'; // greater(5, 6) may be evaluated at compile-time or runtime

    constexpr int g { greater(5, 6) };  // greater(5, 6) must be evaluated at compile-time
    std::cout &lt;&lt; g &lt;&lt; '\n';             // prints 6

    return 0;
}</code></pre>
<p>In this example, <code>greater()</code> is a constexpr function, and <code>greater(5, 6)</code> is a constant expression, which may be evaluated at either compile-time or runtime.  Because <code>std::cout &lt;&lt; greater(5, 6)</code> calls <code>greater(5, 6)</code> in a non-constexpr context, the compiler is free to choose whether to evaluate <code>greater(5, 6</code>) at compile-time or runtime.  When <code>greater(5, 6)</code> is used to initialize constexpr variable <code>g</code>, <code>greater(5, 6)</code> is called in a constexpr context, and must be evaluated at compile-time.</p>
<p>Now consider the following similar example:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

struct Pair
{
    int m_x {};
    int m_y {};

    int greater() const
    {
        return (m_x &gt; m_y  ? m_x : m_y);
    }
};

int main()
{
    Pair p { 5, 6 };                  // inputs are constexpr values
    std::cout &lt;&lt; p.greater() &lt;&lt; '\n'; // p.greater() evaluates at runtime

    constexpr int g { p.greater() };  // compile error: greater() not constexpr
    std::cout &lt;&lt; g &lt;&lt; '\n';

    return 0;
}</code></pre>
<p>In this version, we have an aggregate struct named <code>Pair</code>, and <code>greater()</code> is now a member function.  However, because member function <code>greater()</code> is not constexpr, <code>p.greater()</code> is not a constant expression.  When <code>std::cout &lt;&lt; p.greater()</code> calls <code>p.greater()</code> (in a non-constexpr context), <code>p.greater()</code> will be evaluated at runtime.  However, when we try to use <code>p.greater()</code> to initialize constexpr variable <code>g</code>, we get a compile error, as <code>p.greater()</code> cannot be evaluated at compile-time.</p>
<p>Since the inputs to <code>p</code> are constexpr values (<code>5</code> and <code>6</code>), it seems like <code>p.greater()</code> should be capable of being evaluated at compile-time.  But how do we do that?</p>
<p class="cpp-section cpp-topline" style="clear: both">Constexpr member functions</p>
<p>Just like non-member functions, member functions can be made constexpr via use of the <code>constexpr</code> keyword.  Constexpr member functions can be evaluated at either compile-time or runtime.</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

struct Pair
{
    int m_x {};
    int m_y {};

    constexpr int greater() const // can evaluate at either compile-time or runtime
    {
        return (m_x &gt; m_y  ? m_x : m_y);
    }
};

int main()
{
    Pair p { 5, 6 };
    std::cout &lt;&lt; p.greater() &lt;&lt; '\n'; // okay: p.greater() evaluates at runtime

    constexpr int g { p.greater() };  // compile error: p not constexpr
    std::cout &lt;&lt; g &lt;&lt; '\n';

    return 0;
}</code></pre>
<p>In this example, we&#8217;ve made <code>greater()</code> a constexpr function, so the compiler can evaluate it at either runtime or compile-time.</p>
<p>When we call <code>p.greater()</code> in runtime expression <code>std::cout &lt;&lt; p.greater()</code>, it evaluates at runtime.</p>
<p>However, when <code>p.greater()</code> is used to initialize constexpr variable <code>g</code>, we get a compiler error.  Although <code>greater()</code> is now constexpr, <code>p</code> is still not constexpr, therefore <code>p.greater()</code> is not a constant expression.</p>
<p class="cpp-section cpp-topline" style="clear: both">Constexpr aggregates</p>
<p>Okay, so if we need <code>p</code> to be constexpr, let&#8217;s just make it constexpr:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

struct Pair // Pair is an aggregate
{
    int m_x {};
    int m_y {};

    constexpr int greater() const
    {
        return (m_x &gt; m_y  ? m_x : m_y);
    }
};

int main()
{
    constexpr Pair p { 5, 6 };        // now constexpr
    std::cout &lt;&lt; p.greater() &lt;&lt; '\n'; // p.greater() evaluates at runtime or compile-time

    constexpr int g { p.greater() };  // p.greater() must evaluate at compile-time
    std::cout &lt;&lt; g &lt;&lt; '\n';

    return 0;
}</code></pre>
<p>Since <code>Pair</code> is an aggregate, and aggregates implicitly support constexpr, we&#8217;re done.  This works!  Since <code>p</code> is a constexpr type, and <code>greater()</code> is a constexpr member function, <code>p.greater()</code> is a constant expression and can be used in places where only constant expressions are allowed.</p>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">Related content</p>
<p>We covered aggregates in lesson <a href="https://www.learncpp.com/cpp-tutorial/struct-aggregate-initialization/">13.8 -- Struct aggregate initialization</a>.
</p></div>
<p class="cpp-section cpp-topline" style="clear: both">Constexpr class objects and constexpr constructors</p>
<p>Now let&#8217;s make our <code>Pair</code> a non-aggregate:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

class Pair // Pair is no longer an aggregate
{
private:
    int m_x {};
    int m_y {};

public:
    Pair(int x, int y): m_x { x }, m_y { y } {}

    constexpr int greater() const
    {
        return (m_x &gt; m_y  ? m_x : m_y);
    }
};

int main()
{
    constexpr Pair p { 5, 6 };       // compile error: p is not a literal type
    std::cout &lt;&lt; p.greater() &lt;&lt; '\n';

    constexpr int g { p.greater() };
    std::cout &lt;&lt; g &lt;&lt; '\n';

    return 0;
}</code></pre>
<p>This example is almost identical to the prior one, except <code>Pair</code> is no longer an aggregate (due to having private data members and a constructor).</p>
<p>When we compile this program, we get a compiler error about <code>Pair</code> not being a &#8220;literal type&#8221;.  Say what?</p>
<p>In C++, a <strong>literal type</strong> is any type for which it might be possible to create an object within a constant expression.  Put another way, an object can&#8217;t be constexpr unless the type qualifies as a literal type.  And our non-aggregate <code>Pair</code> does not qualify.</p>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">Nomenclature</p>
<p>A literal and a literal type are distinct (but related) things.  A literal is a constexpr value that is inserted into the source code.  A literal type is a type that can be used as the type of a constexpr value.  A literal always has a literal type.  However, a value or object with a literal type need not be a literal.
</p></div>
<p>The definition of a literal type is complex, and a summary can be found on <a href="https://en.cppreference.com/w/cpp/named_req/LiteralType">cppreference</a>.  However, it&#8217;s worth noting that literal types include:</p>
<ul>
<li>Scalar types (those holding a single value, such as fundamental types and pointers)
</li>
<li>Reference types
</li>
<li>Most aggregates
</li>
<li>Classes that have a constexpr constructor
</li>
</ul>
<p>And now we see why our <code>Pair</code> isn&#8217;t a literal type.  When a class object is instantiated, the compiler will call the constructor function to initialize the object.  And the constructor function in our <code>Pair</code> class is not constexpr, so it can&#8217;t be invoked at compile-time.  Therefore, <code>Pair</code> objects cannot be constexpr.</p>
<p>The fix for this is simple: we just make our constructor <code>constexpr</code> as well:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

class Pair
{
private:
    int m_x {};
    int m_y {};

public:
    constexpr Pair(int x, int y): m_x { x }, m_y { y } {} // now constexpr

    constexpr int greater() const
    {
        return (m_x &gt; m_y  ? m_x : m_y);
    }
};

int main()
{
    constexpr Pair p { 5, 6 };
    std::cout &lt;&lt; p.greater() &lt;&lt; '\n';

    constexpr int g { p.greater() };
    std::cout &lt;&lt; g &lt;&lt; '\n';

    return 0;
}</code></pre>
<p>This works as expected, just like our aggregate version of <code>Pair</code> did.</p>
<div class="cpp-note cpp-lightgreenbackground">
<p class="cpp-note-title cpp-bottomline">Best practice</p>
<p>If you want your class to be able to be evaluated at compile-time, make your member functions and constructor constexpr.
</p></div>
<p>Implicitly defined constructors are constexpr if they can be defined as such.  Explicitly defaulted constructors must be explicitly defined as constexpr.</p>
<div class="cpp-note cpp-lightbluebackground">
<p class="cpp-note-title cpp-bottomline">Tip</p>
<p>Constexpr is part of the interface of the class, and removing it later will break callers who are calling the function in a constant context.
</p></div>
<p class="cpp-section cpp-topline" style="clear: both">Constexpr members may be needed with non-constexpr/non-const objects</p>
<p>In the above example, since the initializer of constexpr variable <code>g</code> must be a constant expression, it&#8217;s clear that <code>p.greater()</code> must be a constant expression, and therefore <code>p</code>, the <code>Pair</code> constructor, and <code>greater()</code> must all be constexpr.</p>
<p>However, if we replace <code>p.greater()</code> with a constexpr function, things get a little less obvious:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

class Pair
{
private:
    int m_x {};
    int m_y {};

public:
    constexpr Pair(int x, int y): m_x { x }, m_y { y } {}

    constexpr int greater() const
    {
        return (m_x &gt; m_y  ? m_x : m_y);
    }
};

constexpr int init()
{
    Pair p { 5, 6 };    // requires constructor to be constexpr when evaluated at compile-time
    return p.greater(); // requires greater() to be constexpr when evaluated at compile-time
}

int main()
{
    constexpr int g { init() }; // init() evaluated in compile-time context
    std::cout &lt;&lt; g &lt;&lt; '\n';

    return 0;
}</code></pre>
<p>Remember that a constexpr function can evaluate at either runtime or compile-time.  And when a constexpr function evaluates at compile-time, it can only call functions capable of evaluating at compile-time.  In the case of a class type, that means constexpr member functions.</p>
<p>Since <code>g</code> is constexpr, <code>init()</code> must be evaluated at compile-time.  Within the <code>init()</code> function, we define <code>p</code> as non-constexpr/non-const (because we can, not because we should).  Even though <code>p</code> is not defined as constexpr, <code>p</code> still needs to be created at compile-time, and therefore requires a constexpr <code>Pair</code> constructor.  Similarly, in order for <code>p.greater()</code> to evaluate at compile-time, <code>greater()</code> must be a constexpr member function.  If either the <code>Pair</code> constructor or <code>greater()</code> were not constexpr, the compiler would error.</p>
<div class="cpp-note cpp-lightbluebackground">
<p class="cpp-note-title cpp-bottomline">Key insight</p>
<p>When a constexpr function is evaluating in a compile-time context, only constexpr functions can be called.
</p></div>
<p class="cpp-section cpp-topline" style="clear: both">Constexpr member functions may be const or non-const <span class="cpp-section-pill cpp-section-standard">C++14</span></p>
<p>In C++11, non-static constexpr member functions are implicitly const (except constructors).</p>
<p>However, as of C++14, constexpr member functions are no longer implicitly const.  This means that if you want a constexpr function to be a const function, you must explicitly mark it as such.</p>
<p class="cpp-section cpp-topline" style="clear: both">Constexpr non-const member functions can change data members <span class="cpp-section-pill cpp-section-optional">Optional</span></p>
<p>A constexpr non-const member function can change data members of the class, so long as the implicit object isn&#8217;t const.  This is true even if the function is evaluating at compile-time.</p>
<p>Here&#8217;s a contrived example of this:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

class Pair
{
private:
    int m_x {};
    int m_y {};

public:
    constexpr Pair(int x, int y): m_x { x }, m_y { y } {}

    constexpr int greater() const // constexpr and const
    {
        return (m_x &gt; m_y  ? m_x : m_y);
    }

    constexpr void reset() // constexpr but non-const
    {
        m_x = m_y = 0; // non-const member function can change members
    }

    constexpr const int&amp; getX() const { return m_x; }
};

// This function is constexpr
constexpr Pair zero()
{
    Pair p { 1, 2 }; // p is non-const
    p.reset();       // okay to call non-const member function on non-const object
    return p;
}

int main()
{
    Pair p1 { 3, 4 };
    p1.reset();                     // okay to call non-const member function on non-const object
    std::cout &lt;&lt; p1.getX() &lt;&lt; '\n'; // prints 0
    
    Pair p2 { zero() };             // zero() will be evaluated at runtime
    p2.reset();                     // okay to call non-const member function on non-const object
    std::cout &lt;&lt; p2.getX() &lt;&lt; '\n'; // prints 0

    constexpr Pair p3 { zero() };   // zero() will be evaluated at compile-time
//    p3.reset();                   // Compile error: can't call non-const member function on const object
    std::cout &lt;&lt; p3.getX() &lt;&lt; '\n'; // prints 0

    return 0;
}</code></pre>
<p>As we work through this example, remember:</p>
<ul>
<li>A non-const member function can modify members of non-const objects.
</li>
<li>A constexpr member function can be called in either runtime contexts or compile-time contexts.
</li>
</ul>
<p>These two things work independently.</p>
<p>In the case of <code>p1</code>, <code>p1</code> is non-const.  Therefore, we are allowed to call non-const member function <code>p1.reset()</code> to modify <code>p1</code>.  The fact that <code>reset()</code> is constexpr doesn&#8217;t matter here because nothing we&#8217;re doing requires compile-time evaluation.</p>
<p>The <code>p2</code> case is similar.  In this case, the initializer to <code>p2</code> is a function call to <code>zero()</code>.  Even though <code>zero()</code> is a constexpr function, in this case it is invoked in a runtime context, and acts just like a normal function.  Within <code>zero()</code>, we instantiate non-const <code>p</code>, call non-const member function <code>p.reset()</code> on it, and then return <code>p</code>.  The returned <code>Pair</code> is used as the initializer for <code>p2</code>.  The fact that <code>zero()</code> and <code>reset()</code> are constexpr don&#8217;t matter in this case, because nothing we&#8217;re doing requires compile-time evaluation.</p>
<p>The <code>p3</code> case is the interesting one.  Because <code>p3</code> is constexpr, it must have a constant expression initializer.  Therefore, this call to <code>zero()</code> must evaluate at compile-time.  And because we&#8217;re evaluating in a compile-time context, we can only call constexpr functions.  Inside <code>zero()</code>, <code>p</code> is non-const (which is allowed, even though we&#8217;re evaluating at compile-time).  However, because we&#8217;re in a compile-time context, the constructor used to create <code>p</code> must be constexpr.  And just like the <code>p2</code> case, we&#8217;re allowed to call non-const member function <code>p.reset()</code> on non-const object <code>p</code>.  But because we&#8217;re in a compile-time context, the <code>reset()</code> member function must be constexpr.  The function then returns <code>p</code>, which is used to initialize <code>p3</code>.</p>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">Author&#8217;s note</p>
<p>Yes, we used a non-const object to initialize a constexpr object.  If this breaks your brain, it&#8217;s probably because you haven&#8217;t fully separated const from constexpr.</p>
<p>There is no requirement that a constexpr variable be initialized with a const value.  It may seem that way because most of the time we initialize constexpr variable using literals (which are const) or other constexpr variables (which are implicitly const), and because the terms <code>const</code> and <code>constexpr</code> have similar names.</p>
<p>The requirement is actually that a constexpr variable be initialized with a constant expression.  For functions (and operators), constexpr does not imply const, and constexpr functions (and operators) can make use of non-const objects and even return them.</p>
<p>The important thing isn&#8217;t the const, its that the compiler can determine the value of the object at compile-time.  And in the case of constexpr functions, that&#8217;s possible even when they return a non-const object!
</p></div>
<p class="cpp-section cpp-topline" style="clear: both">Constexpr functions that return const references (or pointers) <span class="cpp-section-pill cpp-section-optional">Optional</span></p>
<p>Normally you won&#8217;t see <code>constexpr</code> and <code>const</code> used right next to each other, but one case where this does happen is when you have a constexpr member function that returns a const reference (or (const) pointer-to-const).</p>
<p>In our <code>Pair</code> class above, <code>getX()</code> is a constexpr member function that returns a const reference:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">    constexpr const int&amp; getX() const { return m_x; }</code></pre>
<p>That&#8217;s a lot of const-ing!</p>
<p>The <code>constexpr</code> indicates that the member function can be evaluated at compile-time.  The <code>const int&amp;</code> is the return type of the function.  The rightmost <code>const</code> means the member-function itself is const so it can be called on const objects.</p>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">As an aside&#8230;</p>
<p>A member function that returned a const pointer to const instead might look something like this:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">constexpr const int* const getXPtr() const { return &amp;m_x; }</code></pre>
<p>Isn&#8217;t it beautiful?  No?  Okay, fine.
</p></div>
<div class="prevnext"><div class="prevnext-inline">
	<a class="nav-link" href="https://www.learncpp.com/cpp-tutorial/chapter-14-summary-and-quiz/">
 <div class="nav-button nav-button-next">
    <div class="nav-button-icon"><i class="fa fa-chevron-circle-right" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Next lesson</div>
      <div class="nav-button-lesson">
        <span class="nav-button-lesson-number">14.x</span>Chapter 14 summary and quiz
      </div>
    </div>
  </div></a>
  	<a class="nav-link" href="/">
  <div class="nav-button nav-button-index">
    <div class="nav-button-icon"><i class="fa fa-home" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Back to table of contents</div>
    </div>
</div></a>
  	<a class="nav-link" href="https://www.learncpp.com/cpp-tutorial/converting-constructors-and-the-explicit-keyword/">
  <div class="nav-button nav-button-prev">
    <div class="nav-button-icon"><i class="fa fa-chevron-circle-left" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Previous lesson</div>
      <div class="nav-button-lesson">
        <span class="nav-button-lesson-number">14.16</span>Converting constructors and the explicit keyword
      </div>
    </div>
  </div></a>
  </div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.learncpp.com/cpp-tutorial/constexpr-aggregates-and-classes/feed/</wfw:commentRss>
			<slash:comments>32</slash:comments>
		
		
			</item>
		<item>
		<title>0.13 &#8212; What language standard is my compiler using?</title>
		<link>https://www.learncpp.com/cpp-tutorial/what-language-standard-is-my-compiler-using/</link>
					<comments>https://www.learncpp.com/cpp-tutorial/what-language-standard-is-my-compiler-using/#comments</comments>
		
		<dc:creator><![CDATA[Alex]]></dc:creator>
		<pubDate>Thu, 18 Apr 2024 17:29:45 +0000</pubDate>
				<category><![CDATA[C++ Tutorial]]></category>
		<guid isPermaLink="false">https://www.learncpp.com/?p=16946</guid>

					<description><![CDATA[The following program is designed to print the name of the language standard your compiler is currently using. You can copy/paste, compile, and run this program to validate that your compiler is using the language standard you expect. PrintStandard.cpp: // This program prints the C++ language standard your compiler is &#8230;]]></description>
										<content:encoded><![CDATA[<p>The following program is designed to print the name of the language standard your compiler is currently using.  You can copy/paste, compile, and run this program to validate that your compiler is using the language standard you expect.</p>
<p style="clear: both"></p> <!-- break around image -->
<p>PrintStandard.cpp:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">// This program prints the C++ language standard your compiler is currently using
// Freely redistributable, courtesy of learncpp.com (https://www.learncpp.com/cpp-tutorial/what-language-standard-is-my-compiler-using/)

#include &lt;iostream&gt;

const int numStandards = 7;
// The C++26 stdCode is a placeholder since the exact code won't be determined until the standard is finalized
const long stdCode[numStandards] = { 199711L, 201103L, 201402L, 201703L, 202002L, 202302L, 202612L};
const char* stdName[numStandards] = { "Pre-C++11", "C++11", "C++14", "C++17", "C++20", "C++23", "C++26" };

long getCPPStandard()
{
    // Visual Studio is non-conforming in support for __cplusplus (unless you set a specific compiler flag, which you probably haven't)
    // In Visual Studio 2015 or newer we can use _MSVC_LANG instead
    // See https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/
#if defined (_MSVC_LANG)
    return _MSVC_LANG;
#elif defined (_MSC_VER)
    // If we're using an older version of Visual Studio, bail out
    return -1;
#else
    // __cplusplus is the intended way to query the language standard code (as defined by the language standards)
    return __cplusplus;
#endif
}

int main()
{
    long standard = getCPPStandard();

    if (standard == -1)
    {
        std::cout &lt;&lt; "Error: Unable to determine your language standard.  Sorry.\n";
        return 0;
    }
    
    for (int i = 0; i &lt; numStandards; ++i)
    {
        // If the reported version is one of the finalized standard codes
        // then we know exactly what version the compiler is running
        if (standard == stdCode[i])
        {
            std::cout &lt;&lt; "Your compiler is using " &lt;&lt; stdName[i]
                &lt;&lt; " (language standard code " &lt;&lt; standard &lt;&lt; "L)\n";
            break;
        }

        // If the reported version is between two finalized standard codes,
        // this must be a preview / experimental support for the next upcoming version.
        if (standard &lt; stdCode[i])
        {
            std::cout &lt;&lt; "Your compiler is using a preview/pre-release of " &lt;&lt; stdName[i]
                &lt;&lt; " (language standard code " &lt;&lt; standard &lt;&lt; "L)\n";
            break;
        }
    }
    
    return 0;
}</code></pre>
<p class="cpp-section cpp-topline" style="clear: both">Build or runtime issues</p>
<p>If you get an error while trying to build this, you may have your project set up incorrectly.  See <a href="https://www.learncpp.com/cpp-tutorial/a-few-common-cpp-problems/">0.8 -- A few common C++ problems</a> for advice on some common issues.  If that does not help, review the lessons starting from <a href="https://www.learncpp.com/cpp-tutorial/installing-an-integrated-development-environment-ide/">0.6 -- Installing an Integrated Development Environment (IDE)</a>.</p>
<p>If the program prints &#8220;Error: Unable to determine your language standard&#8221;, your compiler may be non-conforming.  If you are using a popular compiler and this is the case, please leave a comment below with relevant information (e.g. the name and version of your compiler).</p>
<p>If this program prints a different language standard than you were expecting:</p>
<ul>
<li>Check your IDE settings to ensure your compiler is configured to use the language standard you expect.  See <a href="https://www.learncpp.com/cpp-tutorial/configuring-your-compiler-choosing-a-language-standard/">0.12 -- Configuring your compiler: Choosing a language standard</a> for more information on how to do this for some of the major compilers.  Make sure there are no typos or formatting errors.  Some compilers require setting the language standard for each project rather than globally, so if you&#8217;ve just created a new project, this may be the case.
</li>
</ul>
<p></p>
<ul>
<li>Your IDE or compiler may not even be reading the configuration file you&#8217;re editing (we see occasionally reader feedback on this with VS Code).  If this seems like the case, please consult documentation for your IDE or compiler.
</li>
</ul>
<div class="cpp-note cpp-lightbluebackground">
<p class="cpp-note-title cpp-bottomline">Q: If my compiler is using a preview/pre-release version, should I go back one version?</p>
<p>If you are just learning the language, it&#8217;s not necessary.  Just be aware that some features from the upcoming version of the language may be missing, incomplete, buggy, or may change slightly.
</p></div>
<div class="prevnext"><div class="prevnext-inline">
	<a class="nav-link" href="https://www.learncpp.com/cpp-tutorial/statements-and-the-structure-of-a-program/">
 <div class="nav-button nav-button-next">
    <div class="nav-button-icon"><i class="fa fa-chevron-circle-right" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Next lesson</div>
      <div class="nav-button-lesson">
        <span class="nav-button-lesson-number">1.1</span>Statements and the structure of a program
      </div>
    </div>
  </div></a>
  	<a class="nav-link" href="/">
  <div class="nav-button nav-button-index">
    <div class="nav-button-icon"><i class="fa fa-home" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Back to table of contents</div>
    </div>
</div></a>
  	<a class="nav-link" href="https://www.learncpp.com/cpp-tutorial/configuring-your-compiler-choosing-a-language-standard/">
  <div class="nav-button nav-button-prev">
    <div class="nav-button-icon"><i class="fa fa-chevron-circle-left" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Previous lesson</div>
      <div class="nav-button-lesson">
        <span class="nav-button-lesson-number">0.12</span>Configuring your compiler: Choosing a language standard
      </div>
    </div>
  </div></a>
  </div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.learncpp.com/cpp-tutorial/what-language-standard-is-my-compiler-using/feed/</wfw:commentRss>
			<slash:comments>128</slash:comments>
		
		
			</item>
		<item>
		<title>13.5 &#8212; Introduction to overloading the I/O operators</title>
		<link>https://www.learncpp.com/cpp-tutorial/introduction-to-overloading-the-i-o-operators/</link>
					<comments>https://www.learncpp.com/cpp-tutorial/introduction-to-overloading-the-i-o-operators/#comments</comments>
		
		<dc:creator><![CDATA[Alex]]></dc:creator>
		<pubDate>Mon, 25 Mar 2024 21:51:17 +0000</pubDate>
				<category><![CDATA[C++ Tutorial]]></category>
		<guid isPermaLink="false">https://www.learncpp.com/?p=16842</guid>

					<description><![CDATA[In the prior lesson (), we showed this example, where we used a function to convert an enumeration into an equivalent string: #include &#60;iostream&#62; #include &#60;string_view&#62; enum Color { black, red, blue, }; constexpr std::string_view getColorName(Color color) { switch (color) { case black: return "black"; case red: return "red"; case &#8230;]]></description>
										<content:encoded><![CDATA[<p>In the prior lesson (<a href="https://www.learncpp.com/cpp-tutorial/converting-an-enumeration-to-and-from-a-string/">13.4 -- Converting an enumeration to and from a string</a>), we showed this example, where we used a function to convert an enumeration into an equivalent string:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;
#include &lt;string_view&gt;

enum Color
{
    black,
    red,
    blue,
};

constexpr std::string_view getColorName(Color color)
{
    switch (color)
    {
    case black: return "black";
    case red:   return "red";
    case blue:  return "blue";
    default:    return "???";
    }
}

int main()
{
    constexpr Color shirt{ blue };

    std::cout &lt;&lt; "Your shirt is " &lt;&lt; getColorName(shirt) &lt;&lt; '\n';

    return 0;
}</code></pre>
<p>Although the above example works just fine, there are two downsides:</p>
<ol start="1">
<li>We have to remember the name of the function we created to get the enumerator name.
</li>
<li>Having to call such a function adds clutter to our output statement.
</li>
</ol>
<p>Ideally, it would be nice if we could somehow teach <code>operator&lt;&lt;</code> to output an enumeration, so we could do something like this: <code>std::cout &lt;&lt; shirt</code> and have it do what we expect.</p>
<p class="cpp-section cpp-topline" style="clear: both">Introduction to operator overloading</p>
<p>In lesson <a href="https://www.learncpp.com/cpp-tutorial/introduction-to-function-overloading/">11.1 -- Introduction to function overloading</a>, we introduced function overloading, which allows us to create multiple functions with the same name so long as each function has a unique function prototype.  Using function overloading, we can create variations of a function that work with different data types, without having to think up a unique name for each variant.</p>
<p>Similarly, C++ also supports <strong>operator overloading</strong>, which lets us define overloads of existing operators, so that we can make those operators work with our program-defined data types.</p>
<p>Basic operator overloading is fairly straightforward:</p>
<ul>
<li>Define a function using the name of the operator as the function&#8217;s name.
</li>
<li>Add a parameter of the appropriate type for each operand (in left-to-right order).  One of these parameters must be a user-defined type (a class type or an enumerated type), otherwise the compiler will error.
</li>
<li>Set the return type to whatever type makes sense.
</li>
<li>Use a return statement to return the result of the operation.
</li>
</ul>
<p>When the compiler encounters the use of an operator in an expression and one or more of the operands is a user-defined type, the compiler will check to see if there is an overloaded operator function that it can use to resolve that call.  For example, given some expression <code>x + y</code>, the compiler will use function overload resolution to see if there is an <code>operator+(x, y)</code> function call that it can use to evaluate the operation.  If a non-ambiguous <code>operator+</code> function can be found, it will be called, and the result of the operation returned as the return value.</p>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">Related content</p>
<p>We cover operator overloading in much more detail in chapter <a href="https://www.learncpp.com#Chapter21">chapter 21</a>.
</p></div>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">For advanced readers</p>
<p>Operators can also be overloaded as member functions of the left-most operand.  We discuss this in lesson <a href="https://www.learncpp.com/cpp-tutorial/overloading-operators-using-member-functions/">21.5 -- Overloading operators using member functions</a>.
</p></div>
<p class="cpp-section cpp-topline" style="clear: both"><a name="insertion"></a>Overloading <code>operator&lt;&lt;</code> to print an enumerator <a href="#insertion"><i class="fa fa-link" style="font-size: 0.8em;"></i></a></p>
<p>Before we proceed, let&#8217;s quickly recap how <code>operator&lt;&lt;</code> works when used for output.</p>
<p>Consider a simple expression like <code>std::cout &lt;&lt; 5</code>.  <code>std::cout</code> has type <code>std::ostream</code> (which is a user-defined type in the standard library), and <code>5</code> is a literal of type <code>int</code>.</p>
<p>When this expression is evaluated, the compiler will look for an overloaded <code>operator&lt;&lt;</code> function that can handle arguments of type <code>std::ostream</code> and <code>int</code>.  It will find such a function (also defined as part of the standard I/O library) and call it.  Inside that function, <code>std::cout</code> is used to output <code>x</code> to the console (exactly how is implementation-defined).  Finally, the <code>operator&lt;&lt;</code> function returns its left-operand (which in this case is <code>std::cout</code>), so that subsequent calls to <code>operator&lt;&lt;</code> can be chained.</p>
<p>With the above in mind, let&#8217;s implement an overload of <code>operator&lt;&lt;</code> to print a <code>Color</code>:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;
#include &lt;string_view&gt;

enum Color
{
	black,
	red,
	blue,
};

constexpr std::string_view getColorName(Color color)
{
    switch (color)
    {
    case black: return "black";
    case red:   return "red";
    case blue:  return "blue";
    default:    return "???";
    }
}

// Teach operator&lt;&lt; how to print a Color
// std::ostream is the type of std::cout, std::cerr, etc...
// The return type and parameter type are references (to prevent copies from being made)
std::ostream&amp; operator&lt;&lt;(std::ostream&amp; out, Color color)
{
    out &lt;&lt; getColorName(color); // print our color's name to whatever output stream out 
    return out;                 // operator&lt;&lt; conventionally returns its left operand

    // The above can be condensed to the following single line:
    // return out &lt;&lt; getColorName(color)
}

int main()
{
	Color shirt{ blue };
	std::cout &lt;&lt; "Your shirt is " &lt;&lt; shirt &lt;&lt; '\n'; // it works!

	return 0;
}</code></pre>
<p>This prints:</p>
<pre>
Your shirt is blue
</pre>
<p>Let&#8217;s unpack our overloaded operator function a bit.  First, the name of the function is <code>operator&lt;&lt;</code>, since that is the name of the operator we&#8217;re overloading.  <code>operator&lt;&lt;</code> has two parameters. The left parameter (which will be matched with the left operand) is our output stream, which has type <code>std::ostream</code>.  We use pass by non-const reference here because we don&#8217;t want to make a copy of a <code>std::ostream</code> object when the function is called, but the <code>std::ostream</code> object needs to be modified in order to do output.  The right parameter (which will be matched with the right operand) is our <code>Color</code> object.  Since <code>operator&lt;&lt;</code> conventionally returns its left operand, the return type matches the type of the left-operand, which is <code>std::ostream&amp;</code>.</p>
<p>Now let&#8217;s look at the implementation.  A <code>std::ostream</code> object already knows how to print a <code>std::string_view</code> using <code>operator&lt;&lt;</code> (this comes as part of the standard library).  So <code>out &lt;&lt; getColorName(color)</code> simply fetches our color&#8217;s name as a <code>std::string_view</code> and then prints it to the output stream.</p>
<p>Note that our implementation uses parameter <code>out</code> instead of <code>std::cout</code> because we want to allow the caller to determine which output stream they will output to (e.g. <code>std::cerr &lt;&lt; color</code> should output to <code>std::cerr</code>, not <code>std::cout</code>).</p>
<p>Returning the left operand is also easy.  The left operand is parameter <code>out</code>, so we just return <code>out</code>.</p>
<p>Putting it all together: when we call <code>std::cout &lt;&lt; shirt</code>, the compiler will see that we&#8217;ve overloaded <code>operator&lt;&lt;</code> to work with objects of type <code>Color</code>.  Our overloaded <code>operator&lt;&lt;</code> function is then called with <code>std::cout</code> as the <code>out</code> parameter, and our <code>shirt</code> variable (which has value <code>blue</code>) as parameter <code>color</code>.  Since <code>out</code> is a reference to <code>std::cout</code>, and <code>color</code> is a copy of enumerator <code>blue</code>, the expression <code>out &lt;&lt; getColorName(color)</code> prints <code>"blue"</code> to the console.  Finally <code>out</code> is returned back to the caller in case we want to chain additional output.</p>
<p class="cpp-section cpp-topline" style="clear: both"><a name="extraction"></a>Overloading <code>operator&gt;&gt;</code> to input an enumerator <a href="#extraction"><i class="fa fa-link" style="font-size: 0.8em;"></i></a></p>
<p>Similar to how we were able to teach <code>operator&lt;&lt;</code> to output an enumeration above, we can also teach <code>operator&gt;&gt;</code> how to input an enumeration:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;
#include &lt;limits&gt;
#include &lt;optional&gt;
#include &lt;string&gt;
#include &lt;string_view&gt;

enum Pet
{
    cat,   // 0
    dog,   // 1
    pig,   // 2
    whale, // 3
};

constexpr std::string_view getPetName(Pet pet)
{
    switch (pet)
    {
    case cat:   return "cat";
    case dog:   return "dog";
    case pig:   return "pig";
    case whale: return "whale";
    default:    return "???";
    }
}

constexpr std::optional&lt;Pet&gt; getPetFromString(std::string_view sv)
{
    if (sv == "cat")   return cat;
    if (sv == "dog")   return dog;
    if (sv == "pig")   return pig;
    if (sv == "whale") return whale;

    return {};
}

// pet is an in/out parameter
std::istream&amp; operator&gt;&gt;(std::istream&amp; in, Pet&amp; pet)
{
    std::string s{};
    in &gt;&gt; s; // get input string from user

    std::optional&lt;Pet&gt; match { getPetFromString(s) };
    if (match) // if we found a match
    {
        pet = *match; // dereference std::optional to get matching enumerator
        return in;
    }

    // We didn't find a match, so input must have been invalid
    // so we will set input stream to fail state
    in.setstate(std::ios_base::failbit);
    
    // On an extraction failure, operator&gt;&gt; zero-initializes fundamental types
    // Uncomment the following line to make this operator do the same thing
    // pet = {};

    return in;
}

int main()
{
    std::cout &lt;&lt; "Enter a pet: cat, dog, pig, or whale: ";
    Pet pet{};
    std::cin &gt;&gt; pet;
        
    if (std::cin) // if we found a match
        std::cout &lt;&lt; "You chose: " &lt;&lt; getPetName(pet) &lt;&lt; '\n';
    else
    {
        std::cin.clear(); // reset the input stream to good
        std::cin.ignore(std::numeric_limits&lt;std::streamsize&gt;::max(), '\n');
        std::cout &lt;&lt; "Your pet was not valid\n";
    }

    return 0;
}</code></pre>
<p>There are a few differences from the output case worth noting here.  First, <code>std::cin</code> has type <code>std::istream</code>, so we use <code>std::istream&amp;</code> as the type of our left parameter and return value instead of <code>std::ostream&amp;</code>.  Second, the <code>pet</code> parameter is a non-const reference.  This allows our <code>operator&gt;&gt;</code> to modify the value of the right operand that is passed in if our extraction results in a match.</p>
<div class="cpp-note cpp-lightbluebackground">
<p class="cpp-note-title cpp-bottomline">Key insight</p>
<p>Our right operand (<code>pet</code>) is an out parameter.  We cover out parameters in lesson <a href="https://www.learncpp.com/cpp-tutorial/in-and-out-parameters/">12.13 -- In and out parameters</a>.</p>
<p>If <code>pet</code> was a value parameter rather than a reference parameter, then our <code>operator&gt;&gt;</code> function would end up assigning a new value to a copy of the right operand rather than the actual right operand.  We want our right operand to be modified in this case.
</div>
<p>Inside the function, we use <code>operator&gt;&gt;</code> to input a <code>std::string</code> (something it already knows how to do).  If the value the user enters matches one of our pets, then we can assign <code>pet</code> the appropriate enumerator and return the left operand (<code>in</code>).</p>
<p>If the user did not enter a valid pet, then we handle that case by putting <code>std::cin</code> into &#8220;failure mode&#8221;.  This is the state that <code>std::cin</code> typically goes into when an extraction fails.  The caller can then check <code>std::cin</code> to see if the extraction succeeded or failed.</p>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">Related content</p>
<p>In lesson <a href="https://www.learncpp.com/cpp-tutorial/stdarray-and-enumerations/">17.6 -- std::array and enumerations</a>, we show how we can use <code>std::array</code> to make our input and output operators less redundant, and avoid having to modify them when a new enumerator is added.
</div>
<div class="prevnext"><div class="prevnext-inline">
	<a class="nav-link" href="https://www.learncpp.com/cpp-tutorial/scoped-enumerations-enum-classes/">
 <div class="nav-button nav-button-next">
    <div class="nav-button-icon"><i class="fa fa-chevron-circle-right" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Next lesson</div>
      <div class="nav-button-lesson">
        <span class="nav-button-lesson-number">13.6</span>Scoped enumerations (enum classes)
      </div>
    </div>
  </div></a>
  	<a class="nav-link" href="/">
  <div class="nav-button nav-button-index">
    <div class="nav-button-icon"><i class="fa fa-home" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Back to table of contents</div>
    </div>
</div></a>
  	<a class="nav-link" href="https://www.learncpp.com/cpp-tutorial/converting-an-enumeration-to-and-from-a-string/">
  <div class="nav-button nav-button-prev">
    <div class="nav-button-icon"><i class="fa fa-chevron-circle-left" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Previous lesson</div>
      <div class="nav-button-lesson">
        <span class="nav-button-lesson-number">13.4</span>Converting an enumeration to and from a string
      </div>
    </div>
  </div></a>
  </div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.learncpp.com/cpp-tutorial/introduction-to-overloading-the-i-o-operators/feed/</wfw:commentRss>
			<slash:comments>40</slash:comments>
		
		
			</item>
		<item>
		<title>13.4 &#8212; Converting an enumeration to and from a string</title>
		<link>https://www.learncpp.com/cpp-tutorial/converting-an-enumeration-to-and-from-a-string/</link>
					<comments>https://www.learncpp.com/cpp-tutorial/converting-an-enumeration-to-and-from-a-string/#comments</comments>
		
		<dc:creator><![CDATA[Alex]]></dc:creator>
		<pubDate>Mon, 25 Mar 2024 21:51:15 +0000</pubDate>
				<category><![CDATA[C++ Tutorial]]></category>
		<guid isPermaLink="false">https://www.learncpp.com/?p=16840</guid>

					<description><![CDATA[In the prior lesson (), we showed an example like this: #include &#60;iostream&#62; enum Color { black, // 0 red, // 1 blue, // 2 }; int main() { Color shirt{ blue }; std::cout &#60;&#60; "Your shirt is " &#60;&#60; shirt &#60;&#60; '\n'; return 0; } This prints: Your shirt &#8230;]]></description>
										<content:encoded><![CDATA[<p>In the prior lesson (<a href="https://www.learncpp.com/cpp-tutorial/unscoped-enumerator-integral-conversions/">13.3 -- Unscoped enumerator integral conversions</a>), we showed an example like this:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

enum Color
{
    black, // 0
    red,   // 1
    blue,  // 2
};

int main()
{
    Color shirt{ blue };

    std::cout &lt;&lt; "Your shirt is " &lt;&lt; shirt &lt;&lt; '\n';

    return 0;
}</code></pre>
<p>This prints:</p>
<pre>
Your shirt is 2
</pre>
<p>Because <code>operator&lt;&lt;</code> doesn&#8217;t know how to print a <code>Color</code>, the compiler will implicitly convert <code>Color</code> into an integral value and print that instead.</p>
<p>Most of the time, printing an enumeration as an integral value (such as <code>2</code>) isn&#8217;t what we want.  Instead, we typically want to print the name of whatever the enumerator represents (e.g. <code>blue</code>).  C++ doesn&#8217;t come with an out-of-the-box way to do this, so we&#8217;ll have to find a solution ourselves.  Fortunately, that&#8217;s not very difficult.</p>
<p class="cpp-section cpp-topline" style="clear: both">Getting the name of an enumerator</p>
<p>The typical way to get the name of an enumerator is to write a function that allows us to pass in an enumerator and returns the enumerator&#8217;s name as a string. But that requires some way to determine which string should be returned for a given enumerator.</p>
<p>There are two common ways to do this.</p>
<p>In lesson <a href="https://www.learncpp.com/cpp-tutorial/switch-statement-basics/">8.5 -- Switch statement basics</a>, we noted that a switch statement can switch on either an integral value or an enumerated value.  In the following example, we use a switch statement to select an enumerator and return the appropriate color string literal for that enumerator:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;
#include &lt;string_view&gt;

enum Color
{
    black,
    red,
    blue,
};

constexpr std::string_view getColorName(Color color)
{
    switch (color)
    {
    case black: return "black";
    case red:   return "red";
    case blue:  return "blue";
    default:    return "???";
    }
}

int main()
{
    constexpr Color shirt{ blue };

    std::cout &lt;&lt; "Your shirt is " &lt;&lt; getColorName(shirt) &lt;&lt; '\n';

    return 0;
}</code></pre>
<p>This prints:</p>
<pre>
Your shirt is blue
</pre>
<p>In the above example, we switch on <code>color</code>, which holds the enumerator we passed in.  Inside the switch, we have a case-label for each enumerator of <code>Color</code>.  Each case returns the name of the appropriate color as a C-style string literal.  This C-style string literal gets implicitly converted into a <code>std::string_view</code>, which is returned to the caller.  We also have a default case which returns <code>"???"</code>, in case the user passes in something we didn&#8217;t expect.</p>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">A reminder</p>
<p>Because C-style string literals exist for the entire program, it&#8217;s okay to return a <code>std::string_view</code> that is viewing a C-style string literal.  When the <code>std::string_view</code> is copied back to the caller, the C-style string literal being viewed will still exist.
</div>
<p>The function is constexpr so that we can use the color&#8217;s name in a constant expression.</p>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">Related content</p>
<p>Constexpr functions are covered in lesson <a href="https://www.learncpp.com/cpp-tutorial/constexpr-functions/">F.1 -- Constexpr functions</a>.
</p></div>
<p>While this lets us get the name of an enumerator, if we want to print that name to the console, having to do <code>std::cout &lt;&lt; getColorName(shirt)</code> isn&#8217;t quite as nice as <code>std::cout &lt;&lt; shirt</code>.  We&#8217;ll teach <code>std::cout</code> how to print an enumeration in upcoming lesson <a href="https://www.learncpp.com/cpp-tutorial/introduction-to-overloading-the-i-o-operators/">13.5 -- Introduction to overloading the I/O operators</a>.</p>
<p>The second way to solve the program of mapping enumerators to strings is to use an array.  We cover this in lesson <a href="https://www.learncpp.com/cpp-tutorial/stdarray-and-enumerations/">17.6 -- std::array and enumerations</a>.</p>
<p class="cpp-section cpp-topline" style="clear: both">Unscoped enumerator input</p>
<p>Now let&#8217;s take a look at an input case.  In the following example, we define a <code>Pet</code> enumeration.  Because <code>Pet</code> is a program-defined type, the language doesn&#8217;t know how to input a <code>Pet</code> using <code>std::cin</code>:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;

enum Pet
{
    cat,   // 0
    dog,   // 1
    pig,   // 2
    whale, // 3
};

int main()
{
    Pet pet { pig };
    std::cin &gt;&gt; pet; // compile error: std::cin doesn't know how to input a Pet

    return 0;
}</code></pre>
<p>One simple way to work around this is to read in an integer, and use <code>static_cast</code> to convert the integer to an enumerator of the appropriate enumerated type:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;
#include &lt;string_view&gt;

enum Pet
{
    cat,   // 0
    dog,   // 1
    pig,   // 2
    whale, // 3
};

constexpr std::string_view getPetName(Pet pet)
{
    switch (pet)
    {
    case cat:   return "cat";
    case dog:   return "dog";
    case pig:   return "pig";
    case whale: return "whale";
    default:    return "???";
    }
}

int main()
{
    std::cout &lt;&lt; "Enter a pet (0=cat, 1=dog, 2=pig, 3=whale): ";

    int input{};
    std::cin &gt;&gt; input; // input an integer

    if (input &lt; 0 || input &gt; 3)
        std::cout &lt;&lt; "You entered an invalid pet\n";
    else
    {
        Pet pet{ static_cast&lt;Pet&gt;(input) }; // static_cast our integer to a Pet
        std::cout &lt;&lt; "You entered: " &lt;&lt; getPetName(pet) &lt;&lt; '\n';
    }

    return 0;
}</code></pre>
<p>While this works, it&#8217;s a bit awkward.  Also note that we should only <code>static_cast&lt;Pet&gt;(input)</code> once we know <code>input</code> is in range of the enumerator.</p>
<p class="cpp-section cpp-topline" style="clear: both">Getting an enumeration from a string</p>
<p>Instead of inputting a number, it would be nicer if the user could type in a string representing an enumerator (e.g. &#8220;pig&#8221;), and we could convert that string into the appropriate <code>Pet</code> enumerator.  However, doing this requires us to solve a couple of challenges.</p>
<p>First, we can&#8217;t switch on a string, so we need to use something else to match the string the user passed in.  The simplest approach here is to use a series of if-statements.</p>
<p>Second, what <code>Pet</code> enumerator should we return if the user passes in an invalid string?  One option would be to add an enumerator to represent &#8220;none/invalid&#8221;, and return that.  However, a better option is to use <code>std::optional</code> here.</p>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">Related content</p>
<p>We cover <code>std::optional</code> in lesson <a href="https://www.learncpp.com/cpp-tutorial/stdoptional/">12.15 -- std::optional</a>.
</div>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;iostream&gt;
#include &lt;optional&gt; // for std::optional
#include &lt;string&gt;
#include &lt;string_view&gt;

enum Pet
{
    cat,   // 0
    dog,   // 1
    pig,   // 2
    whale, // 3
};

constexpr std::string_view getPetName(Pet pet)
{
    switch (pet)
    {
    case cat:   return "cat";
    case dog:   return "dog";
    case pig:   return "pig";
    case whale: return "whale";
    default:    return "???";
    }
}

constexpr std::optional&lt;Pet&gt; getPetFromString(std::string_view sv)
{
    // We can only switch on an integral value (or enum), not a string
    // so we have to use if-statements here
    if (sv == "cat")   return cat;
    if (sv == "dog")   return dog;
    if (sv == "pig")   return pig;
    if (sv == "whale") return whale;
    
    return {};
}

int main()
{
    std::cout &lt;&lt; "Enter a pet: cat, dog, pig, or whale: ";
    std::string s{};
    std::cin &gt;&gt; s;
        
    std::optional&lt;Pet&gt; pet { getPetFromString(s) };

    if (!pet)
        std::cout &lt;&lt; "You entered an invalid pet\n";
    else
        std::cout &lt;&lt; "You entered: " &lt;&lt; getPetName(*pet) &lt;&lt; '\n';

    return 0;
}</code></pre>
<p>In the above solution, we use a series of if-else statements to do string comparisons.  If the user&#8217;s input string matches an enumerator string, we return the appropriate enumerator.  If none of the strings match, we return <code>{}</code>, which means &#8220;no value&#8221;.</p>
<div class="cpp-note cpp-lightgraybackground">
<p class="cpp-note-title cpp-bottomline">For advanced readers</p>
<p>Note that the above solution only matches lower case letters.  If you want to match any letter case, you can use the following function to convert the user&#8217;s input to lower case:</p>
<pre class="language-cpp line-numbers"><code class="language-cpp match-braces">#include &lt;algorithm&gt; // for std::transform
#include &lt;cctype&gt;    // for std::tolower
#include &lt;iterator&gt;  // for std::back_inserter
#include &lt;string&gt;
#include &lt;string_view&gt;

// This function returns a std::string that is the lower-case version of the std::string_view passed in.
// Only 1:1 character mapping can be performed by this function
std::string toASCIILowerCase(std::string_view sv)
{
    std::string lower{};
    std::transform(sv.begin(), sv.end(), std::back_inserter(lower),
        [](char c)
        { 
            return static_cast&lt;char&gt;(std::tolower(static_cast&lt;unsigned char&gt;(c)));
        });
    return lower;
}</code></pre>
<p>This function steps through each character in <code>std::string_view sv</code>, converts it to a lower case character using <code>std::tolower()</code> (with the help of a lambda), and then appends that lower-case character to <code>lower</code>.  </p>
<p>We cover lambdas in lesson <a href="https://www.learncpp.com/cpp-tutorial/introduction-to-lambdas-anonymous-functions/">20.6 -- Introduction to lambdas (anonymous functions)</a>.
</p></div>
<p>Similar to the output case, it would be better if we could just <code>std::cin &gt;&gt; pet</code>.  We&#8217;ll cover this in upcoming lesson <a href="https://www.learncpp.com/cpp-tutorial/introduction-to-overloading-the-i-o-operators/">13.5 -- Introduction to overloading the I/O operators</a>.</p>
<div class="prevnext"><div class="prevnext-inline">
	<a class="nav-link" href="https://www.learncpp.com/cpp-tutorial/introduction-to-overloading-the-i-o-operators/">
 <div class="nav-button nav-button-next">
    <div class="nav-button-icon"><i class="fa fa-chevron-circle-right" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Next lesson</div>
      <div class="nav-button-lesson">
        <span class="nav-button-lesson-number">13.5</span>Introduction to overloading the I/O operators
      </div>
    </div>
  </div></a>
  	<a class="nav-link" href="/">
  <div class="nav-button nav-button-index">
    <div class="nav-button-icon"><i class="fa fa-home" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Back to table of contents</div>
    </div>
</div></a>
  	<a class="nav-link" href="https://www.learncpp.com/cpp-tutorial/unscoped-enumerator-integral-conversions/">
  <div class="nav-button nav-button-prev">
    <div class="nav-button-icon"><i class="fa fa-chevron-circle-left" aria-hidden="true"></i></div>
    <div class="nav-button-text">
      <div class="nav-button-title">Previous lesson</div>
      <div class="nav-button-lesson">
        <span class="nav-button-lesson-number">13.3</span>Unscoped enumerator integral conversions
      </div>
    </div>
  </div></a>
  </div></div>
]]></content:encoded>
					
					<wfw:commentRss>https://www.learncpp.com/cpp-tutorial/converting-an-enumeration-to-and-from-a-string/feed/</wfw:commentRss>
			<slash:comments>26</slash:comments>
		
		
			</item>
	</channel>
</rss>
