{"id":5027,"date":"2016-11-13T19:35:27","date_gmt":"2016-11-13T19:35:27","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/constexpr-variables-and-objects\/"},"modified":"2023-06-26T12:36:21","modified_gmt":"2023-06-26T12:36:21","slug":"constexpr-variables-and-objects","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/constexpr-variables-and-objects\/","title":{"rendered":"constexpr &#8211; Variables and Objects"},"content":{"rendered":"<p>If you declare a variable as <span style=\"font-family: courier new,courier;\">constexpr<\/span> the compiler will evaluate them at compile time. This holds not only true for built-in types but also for instantiations of user-defined types. There are a few serious restrictions for objects to evaluate at compile time.<\/p>\n<p>&nbsp;<\/p>\n<p><!--more--><\/p>\n<p>To make it easier, I will use built-in types like<span style=\"font-family: courier new,courier;\"> bool, char, int<\/span>, and <span style=\"font-family: courier new,courier;\">double<\/span>. I will call the remaining data types user-defined data types. These are, for example, <span style=\"font-family: courier new,courier;\">std::string,<\/span> types from the C++ library, and user-defined data types. User-defined types typically hold built-in types.<\/p>\n<h2>Variables<\/h2>\n<p>By using the keyword <span style=\"font-family: courier new,courier;\">constexpr<\/span> the variable becomes a constant expression.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\">constexpr <span style=\"color: #2b91af;\">double<\/span> myDouble= 5.2;\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Therefore, I can use the variable in contexts requiring constant expression. For example, if I want to define the size of an array. This has to be done at compile time.<\/p>\n<p>For the declaration of <span style=\"font-family: courier new,courier;\">constexpr<\/span> variable, you have to keep a few rules in mind.<\/p>\n<p>The variable<\/p>\n<ul>\n<li>is implicitly const.<\/li>\n<li>has to be initialized.<\/li>\n<li>requires a constant expression for initialization.<\/li>\n<\/ul>\n<p>The rule makes sense. If I evaluate a variable at compile time, the variable can only depend on values that can be evaluated at compile time.<\/p>\n<p>The invocation of the constructor creates the objects. The constructor has a few special rules.<\/p>\n<\/p>\n<h2>User-defined types<\/h2>\n<p>The class <span style=\"font-family: courier new,courier;\">MyDistance<\/span> from the post<span style=\"font-family: courier new,courier;\"><\/span> <a href=\"https:\/\/www.modernescpp.com\/index.php\/constant-expressions-with-constexpr\">Constant expressions with<span style=\"font-family: courier new,courier;\"> constexpr <\/span><\/a>fulfills all requirements to be initialized at compile time. But what are the requirements?<\/p>\n<p>A <span style=\"font-family: courier new,courier;\">constexpr<\/span> constructor can only be invoked with constant expressions.<\/p>\n<ol>\n<li>can not use exception handling.<\/li>\n<li>has to be declared as <span style=\"font-family: courier new,courier;\">default<\/span> or <span style=\"font-family: courier new,courier;\">delete<\/span> or the function body must be empty (C++11).<\/li>\n<\/ol>\n<p>The <span style=\"font-family: courier new,courier;\">constexpr<\/span> user-defined type<\/p>\n<ol>\n<li>can not have virtual base classes.<\/li>\n<li>requires that each base object and each non-static member has to be initialized in the initialization list of the constructor or directly in the class body. Consequently, it holds that each used constructor (e.g of a base class) has to be <span style=\"font-family: courier new, courier;\">constexpr<\/span> constructor and that the applied initializers have to be constant expressions.<\/li>\n<\/ol>\n<p>Sorry, but the details are even harder: <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/language\/constexpr\">cppreference.com<\/a>. To make the theory obvious I define the class <span style=\"font-family: courier new,courier;\">MyInt. MyInt<\/span> shows the just mentioned points. The class has in addition <span style=\"font-family: courier new,courier;\">constexpr<\/span> methods. There are special rules for <span style=\"font-family: courier new,courier;\">constexpr<\/span> methods and functions. These rules will follow in the next post, so we can concentrate in this post on the essentials about variables and user-defined types.<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35\r\n36\r\n37\r\n38\r\n39\r\n40\r\n41\r\n42\r\n43\r\n44\r\n45\r\n46\r\n47\r\n48\r\n49\r\n50\r\n51\r\n52\r\n53\r\n54\r\n55\r\n56\r\n57\r\n58\r\n59\r\n60\r\n61\r\n62\r\n63\r\n64\r\n65<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ userdefinedTypes.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;ostream&gt;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">MyInt<\/span>{\r\npublic:\r\n  constexpr MyInt()= <span style=\"color: #0000ff;\">default<\/span>;\r\n  constexpr MyInt(<span style=\"color: #2b91af;\">int<\/span> fir, <span style=\"color: #2b91af;\">int<\/span> sec): myVal1(fir), myVal2(sec){}\r\n  MyInt(<span style=\"color: #2b91af;\">int<\/span> i){\r\n\tmyVal1= i-2;\r\n\tmyVal2= i+3;\r\n  }\r\n  \r\n  constexpr MyInt(<span style=\"color: #0000ff;\">const<\/span> MyInt&amp; oth)= <span style=\"color: #0000ff;\">default<\/span>;\r\n  constexpr MyInt(MyInt&amp;&amp; oth)= <span style=\"color: #0000ff;\">delete<\/span>;\r\n  \r\n  constexpr <span style=\"color: #2b91af;\">int<\/span> getSum(){ <span style=\"color: #0000ff;\">return<\/span> myVal1+myVal2; }\r\n  \r\n  <span style=\"color: #0000ff;\">friend<\/span> std::ostream&amp; <span style=\"color: #0000ff;\">operator<\/span>&lt;&lt; (std::ostream &amp;out, <span style=\"color: #0000ff;\">const<\/span> MyInt&amp; myInt){\r\n    out &lt;&lt; <span style=\"color: #a31515;\">\"(\"<\/span> &lt;&lt; myInt.myVal1 &lt;&lt; <span style=\"color: #a31515;\">\",\"<\/span> &lt;&lt; myInt.myVal2 &lt;&lt; <span style=\"color: #a31515;\">\")\"<\/span>;  \r\n    <span style=\"color: #0000ff;\">return<\/span> out;\r\n  }\r\n\r\nprivate:\r\n  <span style=\"color: #2b91af;\">int<\/span> myVal1= 1998;\r\n  <span style=\"color: #2b91af;\">int<\/span> myVal2= 2003;\r\n\r\n};\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n  \r\n  std::cout &lt;&lt; std::endl;\r\n  \r\n  constexpr MyInt myIntConst1;\r\n  MyInt myInt2;\r\n  \r\n  constexpr <span style=\"color: #2b91af;\">int<\/span> sec= 2014;\r\n  constexpr MyInt myIntConst3(2011,sec);\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"myIntConst3.getSum(): \"<\/span> &lt;&lt; myIntConst3.getSum() &lt;&lt; std::endl;\r\n  \r\n  std::cout &lt;&lt; std::endl;\r\n  \r\n  <span style=\"color: #2b91af;\">int<\/span> a= 1998;\r\n  <span style=\"color: #2b91af;\">int<\/span> b= 2003;\r\n  MyInt myInt4(a,b);\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"myInt4.getSum(): \"<\/span> &lt;&lt; myInt4.getSum() &lt;&lt; std::endl;\r\n  std::cout &lt;&lt; myInt4 &lt;&lt; std::endl;\r\n  \r\n  std::cout &lt;&lt; std::endl;\r\n  \r\n  <span style=\"color: #008000;\">\/\/ constexpr MyInt myIntConst5(2000);  ERROR<\/span>\r\n  MyInt myInt6(2000);\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"myInt6.getSum(): \"<\/span> &lt;&lt; myInt4.getSum() &lt;&lt; std::endl;\r\n  std::cout &lt;&lt; myInt6 &lt;&lt; std::endl;\r\n  \r\n  <span style=\"color: #008000;\">\/\/ constexpr MyInt myInt7(myInt4); ERROR<\/span>\r\n  constexpr MyInt myInt8(myIntConst3);\r\n  \r\n  std::cout &lt;&lt; std::endl;\r\n  \r\n  <span style=\"color: #2b91af;\">int<\/span> arr[myIntConst3.getSum()];\r\n  static_assert( myIntConst3.getSum() == 4025, <span style=\"color: #a31515;\">\"2011 + 2014 should be 4025\"<\/span> );\r\n  \r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The class <span style=\"font-family: courier new,courier;\">MyInt<\/span> has three constructors. A <span style=\"font-family: courier new,courier;\">constexpr<\/span> default constructor (line 8) and a constructor taking two (line 9) and taking one argument (line 10). The constructor with two arguments is a <span style=\"font-family: courier new,courier;\">constexpr<\/span> constructor. Therefore, its body is empty. This holds not true for the non-<span style=\"font-family: courier new,courier;\">constexpr<\/span> constructor with one argument. The definition goes on with a defaulted copy-constructor (line 15) and a deleted move-constructor (line 16).&nbsp; Additionally, the class has two methods, but only the method <span style=\"font-family: courier new,courier;\">getSum<\/span> is a const expression. I can only define the variables <span style=\"font-family: courier new,courier;\">myVal1<\/span> and <span style=\"font-family: courier new,courier;\">myVal2<\/span> (lines 26 and 27) in two ways if I want to use them in <span style=\"font-family: courier new,courier;\">constexpr<\/span> objects. At first, I can initialize them in the initialization list of the constructor (line 9); second, I can initialize them in the class body (lines 26 and 27). The initialization in the initialization list of the constructor has a higher priority. It&#8217;s not allowed to define both variables in the body of the constructor (lines 11 and 12).&nbsp;<\/p>\n<p>To put the theory to practice, here is the output of the program.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5025\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/userdefinedTypes.png\" alt=\"userdefinedTypes\" width=\"426\" height=\"278\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/userdefinedTypes.png 426w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/userdefinedTypes-300x196.png 300w\" sizes=\"auto, (max-width: 426px) 100vw, 426px\" \/><\/p>\n<p>The program shows a few special points:<\/p>\n<ul>\n<li>You can use a <span style=\"font-family: courier new,courier;\">constexpr <\/span>constructor at run time. Of course, there is no constant expression<span style=\"font-family: courier new,courier;\"><\/span> (line 36 and line 46).<\/li>\n<li>If you declare a non-constant expression as <span style=\"font-family: courier new,courier;\">constexpr,<\/span> you will get a compiler error (lines 52 and 57).<\/li>\n<li><span style=\"font-family: courier new,courier;\">constexpr<\/span> constructors can coexist with non-<span style=\"font-family: courier new,courier;\">constexpr<\/span> constructors. The same holds for the methods of a class.<span style=\"font-family: courier new,courier;\"><\/span><\/li>\n<\/ul>\n<p>The key observation is: <strong>A <span style=\"font-family: courier new,courier;\">constexpr<\/span> object can only use <span style=\"font-family: courier new,courier;\">constexpr<\/span> methods.<\/strong><\/p>\n<p>But stop. What&#8217;s the story about the two last lines, 62 and 63, in the <span style=\"font-family: courier new,courier;\">main<\/span> function?<\/p>\n<h3>The proof<\/h3>\n<p>Quite straightforward. They prove that the call <span style=\"font-family: courier new,courier;\">myIntConst3.getSum()<\/span> is performed at compile time.<\/p>\n<p>At first, C++ requires&nbsp;that an array&#8217;s size be a constant expression. Second,<span style=\"font-family: courier new,courier;\"> static_assert<\/span> evaluates its expression at compile time. If not, <span style=\"font-family: courier new,courier;\">static_assert<\/span> will not compile.<\/p>\n<p>If I replace line 63<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\">static_assert( myIntConst3.getSum() == 4025, <span style=\"color: #a31515;\">\"2011 + 2014 should be 4025\"<\/span> );\r\n<\/pre>\n<\/div>\n<p>with the line<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\">static_assert( myIntConst4.getSum() == 4001, <span style=\"color: #a31515;\">\"1998 + 2003 should be 4001\"<\/span> );\r\n<\/pre>\n<\/div>\n<p>, I will get a compiler error.<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5026\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/userdefinedTypesError.png\" alt=\"userdefinedTypesError\" width=\"800\" height=\"229\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/userdefinedTypesError.png 924w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/userdefinedTypesError-300x86.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/userdefinedTypesError-768x220.png 768w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>I think you know it already. In the <a href=\"https:\/\/www.modernescpp.com\/index.php\/constexpr-functions\">next post<\/a><span id=\"transmark\">, <\/span>I will write about <span style=\"font-family: courier new, courier;\">contexpr<\/span> functions. They have with C++11 a lot of restrictions that will almost disappear with C++14. constexpr functions in C++14 feel almost like normal functions. Of course, my points about functions will also hold for methods of classes.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you declare a variable as constexpr the compiler will evaluate them at compile time. This holds not only true for built-in types but also for instantiations of user-defined types. There are a few serious restrictions for objects to evaluate at compile time. &nbsp;<\/p>\n","protected":false},"author":21,"featured_media":5025,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[364],"tags":[428],"class_list":["post-5027","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-embedded","tag-constexpr"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5027","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=5027"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5027\/revisions"}],"predecessor-version":[{"id":6926,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5027\/revisions\/6926"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5025"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5027"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5027"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5027"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}