{"id":5989,"date":"2020-09-16T20:48:47","date_gmt":"2020-09-16T20:48:47","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/constexpr-vector-and-string-in-c-20\/"},"modified":"2023-06-26T09:44:55","modified_gmt":"2023-06-26T09:44:55","slug":"constexpr-vector-and-string-in-c-20","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/constexpr-vector-and-string-in-c-20\/","title":{"rendered":"constexpr std::vector and std::string in C++20"},"content":{"rendered":"<p>Probably the most viral keyword in modern C++ is <code>constexpr<\/code>. With C++20, we have a<code> constexpr std::vector<\/code> and a<code> constexpr std::string<\/code>. Additionally, both containers can be manipulated with the <code>constexpr<\/code> algorithms of the Standard Template Library.&nbsp;<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5945\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/TimelineCpp20CoreLanguage.png\" alt=\"TimelineCpp20CoreLanguage\" width=\"650\" height=\"243\" style=\"display: block; margin-left: auto; margin-right: auto;\" \/><\/p>\n<p>In this post, I want to calculate a few numbers&#8217; sum and product at compile time. Depending on the applied C++ standard, this is challenging or quite comfortable to achieve. Let&#8217;s start with C++11.<\/p>\n<h2>Variadic Templates in C++11<\/h2>\n<p>A variadic template is a template that can be invoked with an arbitrary number of arguments. By using the ellipse (&#8230;)<code>&nbsp;tails<\/code>&nbsp;becomes a so-called parameter pack. Parameter packs can only be packed and unpacked. If the ellipse is left from <code>tails<\/code>, the parameter pack is packed. If the ellipse is right from tail<code>s<\/code>, the parameter pack is unpacked.&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ compiletimeVariadicTemplates.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>...<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> sum;\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;&gt;<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> sum<span style=\"color: #555555;\">&lt;&gt;<\/span> {\r\n  <span style=\"color: #006699; font-weight: bold;\">static<\/span> constexpr <span style=\"color: #007788; font-weight: bold;\">int<\/span> value <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">0<\/span>;\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span> i, <span style=\"color: #007788; font-weight: bold;\">int<\/span>... tail<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> sum<span style=\"color: #555555;\">&lt;<\/span>i, tail...<span style=\"color: #555555;\">&gt;<\/span> {\r\n  <span style=\"color: #006699; font-weight: bold;\">static<\/span> constexpr <span style=\"color: #007788; font-weight: bold;\">int<\/span> value <span style=\"color: #555555;\">=<\/span> i <span style=\"color: #555555;\">+<\/span> sum<span style=\"color: #555555;\">&lt;<\/span>tail...<span style=\"color: #555555;\">&gt;::<\/span>value;\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span>...<span style=\"color: #555555;\">&gt;                                  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span><\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> product;\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;&gt;                                        <span style=\"color: #555555;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span><\/span>                                 <\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> product<span style=\"color: #555555;\">&lt;&gt;<\/span> {\r\n  <span style=\"color: #006699; font-weight: bold;\">static<\/span> constexpr <span style=\"color: #007788; font-weight: bold;\">int<\/span> value <span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">1<\/span>;\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span> i, <span style=\"color: #007788; font-weight: bold;\">int<\/span>... tail<span style=\"color: #555555;\">&gt;                      <span style=\"color: #555555;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span><\/span><\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> product<span style=\"color: #555555;\">&lt;<\/span>i, tail...<span style=\"color: #555555;\">&gt;<\/span> {\r\n  <span style=\"color: #006699; font-weight: bold;\">static<\/span> constexpr <span style=\"color: #007788; font-weight: bold;\">int<\/span> value <span style=\"color: #555555;\">=<\/span> i <span style=\"color: #555555;\">*<\/span> product<span style=\"color: #555555;\">&lt;<\/span>tail...<span style=\"color: #555555;\">&gt;::<\/span>value;\r\n};\r\n\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"sum&lt;1, 2, 3, 4, 5&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> sum<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">3<\/span>, <span style=\"color: #ff6600;\">4<\/span>, <span style=\"color: #ff6600;\">5<\/span><span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"product&lt;1, 2, 3, 4, 5&gt;::value: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> product<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">3<\/span>, <span style=\"color: #ff6600;\">4<\/span>, <span style=\"color: #ff6600;\">5<\/span><span style=\"color: #555555;\">&gt;::<\/span>value <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The program calculates the sum and the product of the numbers 1 to 5 at compile time. In the case of the function template <code>product<\/code>, line (1) declares the primary template, line (2) the full specialization for zero arguments, and line (3) the partial specialization for at least one argument. The definition of the primary template (1) is unnecessary if you don&#8217;t use it. The partial specialization (3) starts a recursive instantiation, which ends when all template arguments are consumed. In this case, the full specialization for zero arguments kicks in as the boundary condition. To know how this pack expansion is performed, study the example <span style=\"font-family: courier new, courier;\">compileTimeVariadicTemplates.cpp<\/span> at<a href=\"https:\/\/cppinsights.io\/s\/33f60630\"> C++ Insights<\/a>. <span style=\"color: #555555;\"><span style=\"color: #0099ff; font-style: italic;\"><\/span><\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5984\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/compileTimeVariadicTemplate.png\" alt=\"compileTimeVariadicTemplate\" width=\"450\" height=\"191\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/compileTimeVariadicTemplate.png 533w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/compileTimeVariadicTemplate-300x127.png 300w\" sizes=\"auto, (max-width: 450px) 100vw, 450px\" \/><\/p>\n<p>Thanks to fold expression, calculating at compile-time becomes way more manageable.<\/p>\n<\/p>\n<h2>Fold Expressions in C++17<\/h2>\n<p>With C++17, we can directly reduce a parameter pack with a binary operator.<\/p>\n<p>&nbsp;<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ compiletimeFoldExpressions.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span>... Args<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> sum(<span style=\"color: #006699; font-weight: bold;\">const<\/span> Args<span style=\"color: #555555;\">&amp;<\/span>... args)\r\n{\r\n  <span style=\"color: #006699; font-weight: bold;\">return<\/span> (args <span style=\"color: #555555;\">+<\/span> ...);\r\n}\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span>... Args<span style=\"color: #555555;\">&gt;<\/span>\r\n<span style=\"color: #006699; font-weight: bold;\">auto<\/span> product(<span style=\"color: #006699; font-weight: bold;\">const<\/span> Args<span style=\"color: #555555;\">&amp;<\/span>... args)\r\n{\r\n  <span style=\"color: #006699; font-weight: bold;\">return<\/span> (args <span style=\"color: #555555;\">*<\/span> ...);\r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> main() {\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"sum(1, 2, 3, 4, 5): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> sum(<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">3<\/span>, <span style=\"color: #ff6600;\">4<\/span>, <span style=\"color: #ff6600;\">5<\/span>) <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"product(1, 2, 3, 4, 5): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> product(<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">3<\/span>, <span style=\"color: #ff6600;\">4<\/span>, <span style=\"color: #ff6600;\">5<\/span>) <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The program <code>compiletimeFoldExpressions.cpp<\/code> produces the same result at compile-time, such as the previous program <span style=\"font-family: courier new, courier;\">compileTimeVariadicTemplates.cpp<\/span>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5985\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/compiletimeFoldExpressions.png\" alt=\"compiletimeFoldExpressions\" width=\"450\" height=\"185\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/compiletimeFoldExpressions.png 627w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/compiletimeFoldExpressions-300x123.png 300w\" sizes=\"auto, (max-width: 450px) 100vw, 450px\" \/><\/p>\n<p>Of course, there is more to write about fold expression. Please read the details in my previous post to <a href=\"https:\/\/www.modernescpp.com\/index.php\/component\/content\/article\/42-blog\/functional\/268-fold-expressions?Itemid=239\">Fold Expressions<\/a>.<\/p>\n<p>Now I want to dive into C++20.<\/p>\n<h2>constexpr Containers and Algorithms in C++20<\/h2>\n<p>C++20 supports the <code>constexpr<\/code> containers<code> std::vector<\/code> and <code>std::string. constexpr<\/code> means, in this case, that the member functions of both containers can be applied at compile-time.<\/p>\n<p>Before I write about both containers<code><\/code><code><\/code>, I have to make a short detour to C++17. The reason is simple: No compiler so far supports the <code>constexpr<\/code> <code>std::vector<\/code> and<code> std::string<\/code>. In contrast, the GCC and the Microsoft Compiler support the&nbsp;<code>constexpr<\/code> algorithms of the STL.<\/p>\n<p>In my following example, I use instead of a <code>constexpr std::vector<\/code> a <code>constexpr std::array. <\/code>Since&nbsp;C++17<code> std::array<\/code> can be declared as <code>constexpr: constexpr std::array myArray{1, 2, 3}. <\/code><\/p>\n<p>Now starts the fun part. With C++20, you can use a<code> std::array<\/code> at compile-time.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ constexprArray.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;numeric&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;array&gt;<\/span>\r\n\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n    constexpr std<span style=\"color: #555555;\">::<\/span>array myArray{<span style=\"color: #ff6600;\">1<\/span>, <span style=\"color: #ff6600;\">2<\/span>, <span style=\"color: #ff6600;\">3<\/span>, <span style=\"color: #ff6600;\">4<\/span>, <span style=\"color: #ff6600;\">5<\/span>};                                     <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n    constexpr <span style=\"color: #006699; font-weight: bold;\">auto<\/span> sum <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>accumulate(myArray.begin(), myArray.end(), <span style=\"color: #ff6600;\">0<\/span>);         <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"sum: \"<\/span>  <span style=\"color: #555555;\">&lt;&lt;<\/span> sum <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n    constexpr <span style=\"color: #006699; font-weight: bold;\">auto<\/span> product <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>accumulate(myArray.begin(), myArray.end(), <span style=\"color: #ff6600;\">1<\/span>,      <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span><br \/>                                             std<span style=\"color: #555555;\">::<\/span>multiplies<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span>());\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"product: \"<\/span>  <span style=\"color: #555555;\">&lt;&lt;<\/span> product <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n    constexpr <span style=\"color: #006699; font-weight: bold;\">auto<\/span> product2 <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>accumulate(myArray.begin(), myArray.end(), <span style=\"color: #ff6600;\">1<\/span>,     <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span><br \/>                                              [](<span style=\"color: #006699; font-weight: bold;\">auto<\/span> a, <span style=\"color: #006699; font-weight: bold;\">auto<\/span> b) { <span style=\"color: #006699; font-weight: bold;\">return<\/span> a <span style=\"color: #555555;\">*<\/span> b;});\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"product2: \"<\/span>  <span style=\"color: #555555;\">&lt;&lt;<\/span> product2 <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The<code> std::array<\/code> (1) and all results of the calculations are declared as <code>constexpr<\/code>. Line (2) calculates the sum of all elements, and lines (3) and (4) calculate the product of all elements of<code> myArray<\/code>. Line 2 is valid because <code>myArray<\/code> is a <code>constexpr<\/code> container and the algorithm <code>std::accumulate<\/code> is declared as <code>constexpr<\/code>. Lines (3) and (4) are more interesting. The call operator&nbsp; <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/utility\/functional\/multiplies\"><code>std::multiplies<\/code><\/a> is <code>constexpr<\/code> and since C++17 lambda expression can be <code>constexpr<\/code>.<\/p>\n<p>Here is the output of the program:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5986\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/constexprArray.PNG\" alt=\"constexprArray\" width=\"400\" height=\"196\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/constexprArray.PNG 500w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/constexprArray-300x146.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>Thanks to the<a href=\"https:\/\/godbolt.org\/z\/ezv7Po\"> Compiler Explorer<\/a>, I can present the results way more impressive. Here are the relevant assembler instructions of GCC.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5987\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/constexprArrayCompilerExplorer.PNG\" alt=\"constexprArrayCompilerExplorer\" style=\"display: block; margin-left: auto; margin-right: auto;\" width=\"406\" height=\"368\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/constexprArrayCompilerExplorer.PNG 406w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/constexprArrayCompilerExplorer-300x272.png 300w\" sizes=\"auto, (max-width: 406px) 100vw, 406px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>Lines 19, 29, and 39 show that the results of the array calculations become values in the assembler instructions.&nbsp; This means <code>std::accumulate<\/code> is performed at compile-time, and the calculation result is just available at run-time.<\/p>\n<p>As I already mentioned, no compiler so far supports a <code>constexpr std::vector<\/code> or a<code> constexpr std::string<\/code>. Consequently, I must cheat and assume that my compiler fully supports both <code>constexpr<\/code> containers.<\/p>\n<p>&nbsp;<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ constexprVectorString.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;algorithm&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;string&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;vector&gt;<\/span>\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n    constexpr std<span style=\"color: #555555;\">::<\/span>vector myVec {<span style=\"color: #ff6600;\">15<\/span>, <span style=\"color: #555555;\">-<\/span><span style=\"color: #ff6600;\">5<\/span>, <span style=\"color: #ff6600;\">0<\/span>, <span style=\"color: #ff6600;\">5<\/span>, <span style=\"color: #ff6600;\">10<\/span>};\r\n    constexpr std<span style=\"color: #555555;\">::<\/span>sort(myVec.begin(), myVec.end());\r\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span> v<span style=\"color: #555555;\">:<\/span> myVec) std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> v <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n\\n<\/span><span style=\"color: #cc3300;\">\"<\/span>;\r\n\r\n    <span style=\"color: #006699; font-weight: bold;\">using<\/span> <span style=\"color: #006699; font-weight: bold;\">namespace<\/span> std<span style=\"color: #555555;\">::<\/span>string_literals;\r\n    constexpr std<span style=\"color: #555555;\">::<\/span>vector<span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>string<span style=\"color: #555555;\">&gt;<\/span> myStringVec{<span style=\"color: #cc3300;\">\"Stroustrup\"<\/span>s, <span style=\"color: #cc3300;\">\"Vandevoorde\"<\/span>s, <br \/>                                                   <span style=\"color: #cc3300;\">\"Sutter\"<\/span>s, <span style=\"color: #cc3300;\">\"Josuttis\"<\/span>s, <span style=\"color: #cc3300;\">\"Wong\"<\/span>s };\r\n    constexpr std<span style=\"color: #555555;\">::<\/span>sort(myStringVec.begin(), myStringVec.end());\r\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">auto<\/span> s<span style=\"color: #555555;\">:<\/span> myStringVec) std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> s <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" \"<\/span>;\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"<\/span><span style=\"color: #cc3300; font-weight: bold;\">\\n\\n<\/span><span style=\"color: #cc3300;\">\"<\/span>;\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>With C++20, you can sort a <code>std::vector<\/code> or a <code>std::string<\/code> at compile-time.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5988\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/constexprVectorString.png\" alt=\"constexprVectorString\" style=\"display: block; margin-left: auto; margin-right: auto;\" width=\"476\" height=\"244\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/constexprVectorString.png 476w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/09\/constexprVectorString-300x154.png 300w\" sizes=\"auto, (max-width: 476px) 100vw, 476px\" \/><\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>C++20 adds many convenience functions to make working with containers of the Standard Template Library easier. For example, due to the functions <span style=\"font-family: 'courier new', courier;\">std::erase<\/span> and <span style=\"font-family: 'courier new', courier;\">std::erase_if<\/span>, the deletion of container elements works like a charm. When you want to know if a specific element is in an associative container, the member function <code>contains<\/code> is quite handy.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Probably the most viral keyword in modern C++ is constexpr. With C++20, we have a constexpr std::vector and a constexpr std::string. Additionally, both containers can be manipulated with the constexpr algorithms of the Standard Template Library.&nbsp;<\/p>\n","protected":false},"author":21,"featured_media":5945,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[375],"tags":[428,455],"class_list":["post-5989","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c-20","tag-constexpr","tag-vector"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5989","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=5989"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5989\/revisions"}],"predecessor-version":[{"id":6728,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5989\/revisions\/6728"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5945"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5989"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5989"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5989"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}