{"id":4397,"date":"2022-01-01T14:45:14","date_gmt":"2022-01-01T12:45:14","guid":{"rendered":"https:\/\/mariusbancila.ro\/blog\/?p=4397"},"modified":"2022-01-06T17:48:08","modified_gmt":"2022-01-06T15:48:08","slug":"the-evolution-of-functions-in-modern-cpp","status":"publish","type":"post","link":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/01\/the-evolution-of-functions-in-modern-cpp\/","title":{"rendered":"The Evolution of Functions in Modern C++"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">In programming, a function is a block of code that performs a computational task. (In practice, people write functions that perform many tasks, which is not very good, but it&#8217;s a topic beyond the purpose of this article). Functions are a fundamental concept of programming languages and C++ makes no exception. In fact, in C++ there is a large variety of functions that has evolved over time. In this article, I will give a brief walkthrough of this evolution starting with C++11. Since there are many things to talk about, I will not get into too many details on these topics but will provide various links for you to follow if you want to learn more.<\/p>\n\n\n\n<!--more-->\n\n\n\t\t\t\t<div class=\"wp-block-uagb-table-of-contents uagb-toc__align-left uagb-toc__columns-1  uagb-block-212fb648      \"\n\t\t\t\t\tdata-scroll= \"1\"\n\t\t\t\t\tdata-offset= \"30\"\n\t\t\t\t\tstyle=\"\"\n\t\t\t\t>\n\t\t\t\t<div class=\"uagb-toc__wrap\">\n\t\t\t\t\t\t<div class=\"uagb-toc__title\">\n\t\t\t\t\t\t\tTable Of Contents\t\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div class=\"uagb-toc__list-wrap \">\n\t\t\t\t\t\t<ol class=\"uagb-toc__list\"><li class=\"uagb-toc__list\"><a href=\"#pre-c11\" class=\"uagb-toc-link__trigger\">Pre-C++11<\/a><li class=\"uagb-toc__list\"><a href=\"#c11\" class=\"uagb-toc-link__trigger\">C++11<\/a><ul class=\"uagb-toc__list\"><li class=\"uagb-toc__list\"><a href=\"#variadic-function-templates\" class=\"uagb-toc-link__trigger\">Variadic function templates<\/a><li class=\"uagb-toc__list\"><li class=\"uagb-toc__list\"><a href=\"#alternative-function-syntax\" class=\"uagb-toc-link__trigger\">Alternative function syntax<\/a><li class=\"uagb-toc__list\"><li class=\"uagb-toc__list\"><a href=\"#constexpr-functions\" class=\"uagb-toc-link__trigger\">constexpr functions<\/a><li class=\"uagb-toc__list\"><li class=\"uagb-toc__list\"><a href=\"#override-and-final-specifiers-for-virtual-functions\" class=\"uagb-toc-link__trigger\">Override and final specifiers for virtual functions<\/a><li class=\"uagb-toc__list\"><li class=\"uagb-toc__list\"><a href=\"#more-special-member-functions\" class=\"uagb-toc-link__trigger\">More special member functions<\/a><li class=\"uagb-toc__list\"><li class=\"uagb-toc__list\"><a href=\"#default-and-deleted-functions\" class=\"uagb-toc-link__trigger\">Default and deleted functions<\/a><li class=\"uagb-toc__list\"><li class=\"uagb-toc__list\"><a href=\"#lambdas\" class=\"uagb-toc-link__trigger\">Lambdas<\/a><\/li><\/ul><\/li><li class=\"uagb-toc__list\"><a href=\"#c14\" class=\"uagb-toc-link__trigger\">C++14<\/a><ul class=\"uagb-toc__list\"><li class=\"uagb-toc__list\"><a href=\"#function-return-type-deduction\" class=\"uagb-toc-link__trigger\">Function return type deduction<\/a><li class=\"uagb-toc__list\"><li class=\"uagb-toc__list\"><a href=\"#generic-lambdas\" class=\"uagb-toc-link__trigger\">Generic lambdas<\/a><\/li><\/ul><\/li><\/ul><\/li><li class=\"uagb-toc__list\"><a href=\"#c20\" class=\"uagb-toc-link__trigger\">C++20<\/a><ul class=\"uagb-toc__list\"><li class=\"uagb-toc__list\"><a href=\"#immediate-functions\" class=\"uagb-toc-link__trigger\">Immediate functions<\/a><li class=\"uagb-toc__list\"><li class=\"uagb-toc__list\"><a href=\"#abbreviated-function-templates\" class=\"uagb-toc-link__trigger\">Abbreviated function templates<\/a><li class=\"uagb-toc__list\"><li class=\"uagb-toc__list\"><a href=\"#lambda-templates\" class=\"uagb-toc-link__trigger\">Lambda templates<\/a><li class=\"uagb-toc__list\"><li class=\"uagb-toc__list\"><a href=\"#constexpr-virtuals\" class=\"uagb-toc-link__trigger\">constexpr virtuals<\/a><li class=\"uagb-toc__list\"><li class=\"uagb-toc__list\"><a href=\"#coroutines\" class=\"uagb-toc-link__trigger\">Coroutines<\/a><\/ul><\/ul><\/ul><\/ol>\t\t\t\t\t<\/div>\n\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s start briefly with what he had before &#8220;modern&#8221; times.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Pre-C++11<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Functions were available since the beginning of C++, whose first variant was called <em>C with classes<\/em>. This is how a function looks:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">int add(int a, int b)\n{\n   return a + b;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is what we call a <strong><em>non-member function<\/em><\/strong> or a <em><strong>free function<\/strong><\/em>, because it does not belong to any class. There are also member functions, that are part of a class\/struct. These are also referred as <strong><em>methods<\/em><\/strong> (like in most other object-oriented programming languages), although this term is not used anywhere in the C++ standard. Here is an example:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class math\n{\npublic:\n   int add(int a, int b)\n   {\n      return a + b;\n   }\n};<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">There are multiple kinds of functions, including the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>overloaded functions<\/li><\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">int add(int a, int b) {return a + b;}\ndouble add(double a, double b) {return a + b;}<\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li>static functions<\/li><\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">static int add(int a, int b) {return a + b;}\n\nstruct math\n{\n   static int add(int a, int b) {return a + b;}\n}<\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li>inline functions<\/li><\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">inline int add(int a, int b) {return a + b;}\n\nstruct math\n{\n   inline int add(int a, int b);\n}\n\nint match::add(int a, int b) {return a + b;}<\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li>operators<\/li><\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">std::string operator+(std::string const &amp; txt, int n)\n{\n    return txt + std::to_string(n); \/\/ channels your JavaScript energy\n}<\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li>constant member functions<\/li><\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class wrapper\n{\npublic:\n   wrapper(int a): value_(a) {}\n   int get() const {return value_;}\nprivate:\n   int value_;\n};<\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li>virtual member functions<\/li><\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">struct A\n{\n   virtual void f() { std::cout &lt;&lt; \"A::f()\\n\"; }\n};\n\nstruct B : public A\n{\n   virtual void f() { std::cout &lt;&lt; \"B::f()\\n\"; }\n};<\/pre>\n\n\n\n<ul class=\"wp-block-list\"><li>special class functions (default constructor, copy-constructor, copy-assignment operator, and destructor)<\/li><\/ul>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class wrapper\n{\npublic:\n   wrapper() : value_(0) {}\n   wrapper(wrapper const &amp; other) {value_ = other.value_; }\n   wrapper&amp; operator=(wrapper const &amp; other) {if(this != &amp;other) {value_ = other.value_;} }\n   ~wrapper() {}\nprivate:\n   int value_;\n};<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">All these are very simple examples but the point here is not to detail all these features that existed before modern C++. One thing that is missing here, though, is templates. Templates are blueprints that define families of functions or classes. The compiler instantiates actual overloads (in the case of function templates) from their use. Here is an example:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">template &lt;typename T>\nT add(T a, T b)\n{\n   return a + b;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now that we&#8217;ve briefly looked at these, let&#8217;s see what changes modern C++ brought.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">C++11<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Variadic function templates<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">These are function templates with a variable number of arguments.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">template &lt;typename T>\nT add(T a, T b)\n{\n    return a + b;\n}\n\ntemplate &lt;typename T, typename ...Ts>   \/\/ [1]\nT add(T t, Ts ... rest)                 \/\/ [2]\n{\n    return t + add(rest...);            \/\/ [3]\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The ellipsis (<code>...<\/code>)  defines a parameter pack. We can have:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>a template parameter pack, such as <code>typename ... Ts<\/code> at line <strong>[1]<\/strong><\/li><li>a function parameter pack, such as <code>Ts ... rest<\/code> at line <strong>[2]<\/strong><\/li><li>a pack expansion, such as <code>add(rest...)<\/code> at line <strong>[3]<\/strong><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>See also:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/eli.thegreenplace.net\/2014\/variadic-templates-in-c\/\" target=\"_blank\" rel=\"noreferrer noopener\">Variadic templates in C++<\/a><\/li><li><a href=\"https:\/\/www.modernescpp.com\/index.php\/variadic-templates-or-the-power-of-three-dots\" target=\"_blank\" rel=\"noreferrer noopener\">Variadic templates and the power of three dots<\/a><\/li><li><a href=\"https:\/\/kevinushey.github.io\/blog\/2016\/01\/27\/introduction-to-c++-variadic-templates\/\" target=\"_blank\" rel=\"noreferrer noopener\">Introduction to C++ variadic templates<\/a><\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Alternative function syntax<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The return type of a function can be placed at the end of the function declaration, after the <code>-&gt;<\/code> token:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">auto add(int a, int b) -> int\n{\n   return a + b;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">In C++11, this is not of much help for non-template functions, but it&#8217;s important for some function templates. Consider a version of <code>add()<\/code> that takes arguments of different types:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">template&lt;typename T, typename U>\n??? add(T const &amp; a, U const &amp; b)\n{\n    return a + b;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">What should the return type be? With the alternative function syntax we can place the return at the end of the expression and specify it with a <code>decltype<\/code> expression:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">template&lt;typename T, typename U>\nauto add(T const &amp; a, U const &amp; b) -> decltype(a + b)\n{\n    return a + b;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>See also:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/blog.petrzemek.net\/2017\/01\/17\/pros-and-cons-of-alternative-function-syntax-in-cpp\/\" target=\"_blank\" rel=\"noreferrer noopener\">Pros and Cons of Alternative Function Syntax in C++<\/a><\/li><li><a href=\"https:\/\/www.cprogramming.com\/c++11\/c++11-auto-decltype-return-value-after-function.html\" target=\"_blank\" rel=\"noreferrer noopener\">Improved Type Inference in C++11: auto, decltype, and the new function declaration syntax<\/a><\/li><li><a href=\"https:\/\/www.ibm.com\/docs\/en\/zos\/2.3.0?topic=declarators-trailing-return-type-c11\" target=\"_blank\" rel=\"noreferrer noopener\">Trailing return type (C++11)<\/a><\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">constexpr functions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">These are functions that <em>can<\/em> be evaluated at compile-time. The result of evaluating such a function is a compile-time value that can be used anywhere compile-time values are required. To make a function constexpr you need to define it with the <code>constexpr<\/code> keyword, such as in the following example:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">template &lt;typename T>\nconstexpr T add(T a, T b)\n{\n    return a + b;\n}\n\nint main()\n{\n    int arr[add(1,2)] = {1,2,3};    \/\/ [1]\n\n    int a, b;\n    std::cin >> a >> b;\n    std::cout &lt;&lt; add(a, b) &lt;&lt; '\\n';  \/\/ [2]\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Just because a function is declared <code>constexpr<\/code>, doesn&#8217;t mean it is evaluated at compile-time. In the above example:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>the first call to <code>add<\/code> is evaluated at compile-time (line [1]) because all its arguments are integer literals<\/li><li>the second call to <code>add<\/code> (at line [2]) is evaluated at runtime because its arguments are only know at runtime<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>See also:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/constexpr\" target=\"_blank\" rel=\"noreferrer noopener\">constexpr specifier<\/a><\/li><li><a href=\"https:\/\/www.modernescpp.com\/index.php\/constexpr-functions\" target=\"_blank\" rel=\"noreferrer noopener\">constexpr functions<\/a><\/li><li><a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/cpp\/constexpr-cpp?view=msvc-170\" target=\"_blank\" rel=\"noreferrer noopener\">constexpr (C++)<\/a><\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Override and final specifiers for virtual functions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">These new specifies help us better describe virtual functions in derived classes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>override<\/code> specifier used on a virtual function tells the compiler it is an overridden function of a base class virtual function. If the signature does not match, the compiler triggers an error.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">struct A\n{\n   virtual void f(int) {}\n   virtual void g() {}\n};\n\nstruct B : public A\n{\n   void f(int) override {}  \/\/ OK\n   void g(char) override {} \/\/ error, g() does not override anything\n};<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>final<\/code> specifier tells a compiler a virtual function can longer be overridden in a derived class.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">struct A\n{\n   virtual void f() {}\n};\n\nstruct B : public A\n{\n   void f() override final {}\n};\n\nstruct C : public B\n{\n   void f() override {}   \/\/ error, f cannot be overridden anymore\n};<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">It should be mentioned that the <code>final<\/code> specifier can also be used on classes, in which case it prevents a class from being further derived.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>See also:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/override\" target=\"_blank\" rel=\"noreferrer noopener\">override specifier<\/a><\/li><li><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/final\" target=\"_blank\" rel=\"noreferrer noopener\">final specifier<\/a><\/li><li><a href=\"https:\/\/www.fluentcpp.com\/2020\/02\/21\/virtual-final-and-override-in-cpp\/\" target=\"_blank\" rel=\"noreferrer noopener\">Virtual, final and override in C++<\/a><\/li><li><a href=\"https:\/\/www.modernescpp.com\/index.php\/override-and-final\" target=\"_blank\" rel=\"noreferrer noopener\">override and final<\/a><\/li><li><a href=\"https:\/\/www.cppstories.com\/2021\/override-final\/\" target=\"_blank\" rel=\"noreferrer noopener\">Modern C++: Safety and Expressiveness with override and final<\/a><\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">More special member functions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Move semantics are not easy to describe in one sentence. Basically, it&#8217;s a language feature that enables the transfer of ownership of a resource from one object to another. Their purpose is improving performance by avoiding copies of resources that are not really necessary. For classes, these bring two new special functions: <strong><em>move constructor<\/em><\/strong> and <strong><em>move assignment operator<\/em><\/strong>:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">struct buffer\n{\n   buffer()                       \/\/ default constructor\n       :data_(nullptr), size_(0) \n   {}\n    \n   explicit buffer(size_t size)   \/\/ constructor\n       :data_(new char[size]), size_(size)\n   {}\n    \n   ~buffer()                      \/\/ destructor\n   {\n       delete [] data_;\n   }\n   \n   buffer(buffer const &amp; other)   \/\/ copy constructor\n      : data_(new char[other.size_])\n      , size_(other.size_)\n   {\n      std::memcpy(data_, other.data_, size_);\n   }\n    \n   buffer&amp; operator=(buffer const &amp; other) \/\/ copy assignment operator\n   {\n       if(this != &amp;other)\n       {\n           delete [] data_;\n           data_ = new char[other.size_];\n           size_ = other.size_;\n           std::memcpy(data_, other.data_, size_);\n       }\n       \n       return *this;\n   }\n    \n   buffer(buffer&amp;&amp; other)           \/\/ move constructor\n       : data_(std::move(other.data_))\n       , size_(other.size_)\n   {\n      other.data_ = nullptr;\n      other.size_ = 0;\n   }\n    \n   buffer&amp; operator=(buffer&amp;&amp; other) \/\/ move assignment operator\n   {\n       if(this != &amp;other)\n       {\n           delete [] data_;\n           data_ = std::move(other.data_);\n           size_ = other.size_;\n           other.data_ = nullptr;\n           other.size_ = 0;\n       }\n       \n       return *this;\n   }\n    \nprivate:\n   char* data_;\n   size_t size_;\n};\n\nint main()\n{\n  buffer b1;\n  buffer b2(10);\n  buffer b3 = b2;\n  buffer b4 = std::move(b3);\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">See also:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/stackoverflow.com\/questions\/3106110\/what-is-move-semantics\" target=\"_blank\" rel=\"noreferrer noopener\">What is move semantics?<\/a><\/li><li><a href=\"https:\/\/eli.thegreenplace.net\/2011\/12\/15\/understanding-lvalues-and-rvalues-in-c-and-c\" target=\"_blank\" rel=\"noreferrer noopener\">Understanding lvalues and rvalues in C and C++<\/a><\/li><li><a href=\"https:\/\/mbevin.wordpress.com\/2012\/11\/20\/move-semantics\/\" target=\"_blank\" rel=\"noreferrer noopener\">LESSON #5: MOVE&nbsp;SEMANTICS<\/a><\/li><li><a href=\"https:\/\/medium.com\/@lucianoalmeida1\/a-little-bit-about-std-move-efd9d554c09a\" target=\"_blank\" rel=\"noreferrer noopener\">A little bit about std::move<\/a><\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Default and deleted functions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The special member functions (see above) can be generated by the compiler. However, this does not happen in some circumstances. For instance, if any user-defined constructor exists, a default constructor is not generated, or if a move constructor or move assignment operator is defined, then no copy constructor and copy assignment operator is generated. Rather than implementing these by yourself you can explicitly ask the compiler to generate the default implementation, using the <code>= default<\/code> specifier.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">struct foo\n{\n   foo(int) {}      \/\/ user-defined constructor\n   foo() = default; \/\/ compiler generated default constructor\n};<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">On the other hand, sometimes we need some functions or some function overloads to not be available. We can prevent a function from being called by defining it with the <code>= delete<\/code> specifier:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">struct noncopyable\n{\n  noncopyable() = default;\n  noncopyable(noncopyable const &amp;) = delete;\n  noncopyable&amp; operator=(noncopyable const &amp;) = delete;\n};<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Any function can be deleted, not just member functions, or special member functions (as shown in the previous example).<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">template &lt;typename T>\nT add(T a, T b)\n{\n    return a + b;\n}\n\ntemplate &lt;>\nint add&lt;int>(int a, int b) = delete;\n\nint main()\n{\n    add(1, 2); \/\/ error, this specialization is deleted\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">See also:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/member_functions#Special_member_functions\" target=\"_blank\" rel=\"noreferrer noopener\">special member functions<\/a><\/li><li><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/function#Deleted_functions\" target=\"_blank\" rel=\"noreferrer noopener\">deleted functions<\/a><\/li><li><a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/cpp\/explicitly-defaulted-and-deleted-functions?view=msvc-170\" target=\"_blank\" rel=\"noreferrer noopener\">Explicitly defaulted and deleted functions<\/a><\/li><li><a href=\"https:\/\/abseil.io\/tips\/143\" target=\"_blank\" rel=\"noreferrer noopener\">Tip of the Week #143: C++11 Deleted Functions (<code>= delete<\/code>)<\/a><\/li><li><a href=\"http:\/\/C++11: defaulted and deleted functions\" target=\"_blank\" rel=\"noreferrer noopener\">C++11: defaulted and deleted functions<\/a><\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Lambdas<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Lambdas are not really functions in C++ and the term <em><strong>lambda function<\/strong><\/em> is incorrect. The right term is <strong><em>lambda expressions<\/em><\/strong>. Lambdas are syntactic sugar for creating unnamed function objects (which can capture variables in scope). A function object is a class with an overloaded call operator.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">int main()\n{\n    auto add = [](int a, int b) { return a + b; };\n    add(1, 2);\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The compiler would generate something as follows (conceptually, as the details may vary):<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">int main()\n{\n  class __lambda_1_10\n  {\n    public: \n    inline int operator()(int a, int b) const\n    {\n      return a + b;\n    }    \n  };\n  \n  __lambda_1_10 add = __lambda_1_10 {};\n  add.operator()(1, 2);\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Lambdas are useful for encapsulating a few lines of code that are then passed to functions such as general purpose algorithms or asynchronous functions.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">int main()\n{\n    std::vector&lt;int> v {1, 5, 9, 2, 7};\n    \n    std::sort(v.begin(), v.end(), [](int a, int b){return a > b;}); \/\/ sorts descending\n    \n    for(const auto &amp; e : v)\n        std::cout &lt;&lt; e &lt;&lt; '\\n';\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>See also:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/lambda\" target=\"_blank\" rel=\"noreferrer noopener\">lambda expressions<\/a><\/li><li><a href=\"https:\/\/docs.microsoft.com\/en-us\/cpp\/cpp\/lambda-expressions-in-cpp?view=msvc-170\" target=\"_blank\" rel=\"noreferrer noopener\">lambda expressions in C++<\/a><\/li><li><a href=\"https:\/\/www.cprogramming.com\/c++11\/c++11-lambda-closures.html\" target=\"_blank\" rel=\"noreferrer noopener\">Lambda Functions in C++11 &#8211; the Definitive Guide<\/a><\/li><\/ul>\n\n\n\n<h1 class=\"wp-block-heading\">C++14<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Function return type deduction<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The alternative function syntax with trailing return type got simplified in C++14 with the compiler being able to deduce the return type from the return expression(s) present in the body of a function. Therefore, functions can be simplified as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">auto add(int a, int b)\n{\n   return a + b;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Again, this is more useful in template code:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">template &lt;typename T, typename U>\nauto add(T a, U b)\n{\n   return a + b;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>See also:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/www.modernescpp.com\/index.php\/automatic-return-type-c-11-14-20\" target=\"_blank\" rel=\"noreferrer noopener\">Automatic Return Type (C++11\/14\/20)<\/a><\/li><li><a href=\"https:\/\/www.learncpp.com\/cpp-tutorial\/type-deduction-for-functions\/\" target=\"_blank\" rel=\"noreferrer noopener\">Type deduction for functions<\/a><\/li><li><a href=\"https:\/\/www.rangakrish.com\/index.php\/2016\/04\/08\/c14-return-type-deduction-for-normal-functions\/\">C++14: Return Type Deduction for Normal Functions<\/a><\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Generic lambdas<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A generic lambda is a lambda expression with at least one parameter specified with the <code>auto<\/code> specifier.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">int main()\n{\n    using namespace std::string_literals;\n    \n    auto add = [](auto a, auto b) {return a + b;};\n    \n    add(1, 2);\n    add(1.0, 2.0);\n    add(\"1\"s, \"2\"s);\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This has the effect that the anonymous structure generated by the compiler has a template function call operator. For the above example, it would look, at least conceptually, as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">int main()\n{\n  using namespace std::string_literals;\n    \n  class __lambda_8_16\n  {\n    public: \n    template &lt;typename T0, typename T1>\n    inline auto operator()(T0 a, T1 b) const\n    {\n      return a + b;\n    }\n    \n    template&lt;>\n    inline int operator()(int a, int b) const\n    {\n      return a + b;\n    }\n\n    template&lt;>\n    inline double operator()(double a, double b) const\n    {\n      return a + b;\n    }\n\n    template&lt;>\n    inline std::string operator()(std::string a, std::string b) const\n    {\n      return std::operator+(a, b);\n    }\n  };\n  \n  __lambda_8_16 add = __lambda_8_16{};\n  add.operator()(1, 2);\n  add.operator()(1.0, 2.0);\n  add.operator()(std::operator\"\"s(\"1\", 1UL), std::operator\"\"s(\"2\", 1UL));\n}\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>See also:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/isocpp.org\/wiki\/faq\/cpp14-language#generic-lambdas\" target=\"_blank\" rel=\"noreferrer noopener\">Generic lambdas<\/a><\/li><li><a href=\"https:\/\/riptutorial.com\/cplusplus\/example\/1969\/generic-lambdas\" target=\"_blank\" rel=\"noreferrer noopener\">Generic lambdas<\/a><\/li><li><a href=\"https:\/\/www.cppstories.com\/2020\/08\/lambda-generic.html\/\" target=\"_blank\" rel=\"noreferrer noopener\">Lambda Week: Going Generic<\/a><\/li><\/ul>\n\n\n\n<h1 class=\"wp-block-heading\">C++20<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Immediate functions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Constexpr functions from C++11 can be evaluated either at compile-time (if all arguments are compile-time values) or runtime. C++20 adds a new categories of functions, called <strong><em>immediate functions<\/em><\/strong>, that must be evaluated at compile-time. They always produce a compile-time expression and they are always visible only at compile-time. Symbols are not emitted for these functions, you cannot take the address of such functions, and tools such as debuggers will not be able to show them. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">These functions are defined using the new <code>consteval<\/code> keyword. Here is an example:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">consteval int add(int const a, int const b)\n{\n   return a + b;\n} \n\nint main()\n{\n   constexpr int s1 = add(1, 2);   \/\/ OK, compile-time evaluation\n   int a = 12, b = 66;\n   const int s2 = add(a, b);       \/\/ error\n    \n   using fptr = int(int, int);\n   fptr* padd = add;               \/\/ error\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A&nbsp;<code>consteval<\/code>&nbsp;specifier implies&nbsp;<code>inline<\/code>. A function that is&nbsp;<code>consteval<\/code>&nbsp;is a&nbsp;<code>constexpr<\/code>&nbsp;function, and must satisfy the requirements applicable to&nbsp;<code>constexpr<\/code>&nbsp;functions (or&nbsp;<code>constexpr<\/code>&nbsp;constructors).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>See also:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/consteval\" target=\"_blank\" rel=\"noreferrer noopener\">consteval specifier<\/a><\/li><li><a href=\"https:\/\/mariusbancila.ro\/blog\/2019\/09\/10\/let-there-be-constants\/\" target=\"_blank\" rel=\"noreferrer noopener\">Let there be constants!<\/a><\/li><li><a href=\"https:\/\/www.modernescpp.com\/index.php\/c-20-consteval-and-constinit\" target=\"_blank\" rel=\"noreferrer noopener\">Two new Keywords in C++20: consteval and constinit<\/a><\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Abbreviated function templates<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If you find template syntax ugly or difficult this feature is for you. It allows you to write function templates without using template syntax. Instead, you use the auto specifier to define function parameters. A function with a least one parameter specified with the auto specifier is an abbreviated function template:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">auto add(auto a, auto b)\n{\n   return a + b;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The compiler transforms this into a function template:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">template &lt;typename T, typename U>\nauto add(T a, U b)\n{\n   return a + b;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">These are actually called <strong><em>unconstrained abbreviated function templates<\/em><\/strong> because there are no constraints on the template arguments. However, you can specify constraints with the help of concepts. Such functions are called <strong><em>constrained abbreviated function templates<\/em><\/strong>.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">auto add(std::integral auto a, std::integral auto b)\n{\n   return a + b;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is the same as follows:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">template &lt;std::integral T, std::integral U>\nauto add(T a, U b)\n{\n   return a + b;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>See also:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/function_template\" target=\"_blank\" rel=\"noreferrer noopener\">Function template<\/a><\/li><li><a href=\"https:\/\/devblogs.microsoft.com\/cppblog\/abbreviated-function-templates-and-constrained-auto\/\" target=\"_blank\" rel=\"noreferrer noopener\">Abbreviated Function Templates and Constrained Auto<\/a><\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Lambda templates<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The generic lambdas in C++14 have some shortcomings. For instance, consider this lambda:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">auto add = [](auto a, auto b) {return a + b;};<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The compiler generates the following function object:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">struct _lambda_1\n{\n    template &lt;typename T0, typename T1>\n    inline auto operator()(T0 a, T1 b) const\n    {\n      return a + b;\n    }  \n};<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">But what if the intention is that the two arguments, <code>a<\/code> and <code>b<\/code>, to be of the same type? There is no way to model that in C++14. For this reason, C++20 introduces lambda template, that allows us to define generic lambdas using template syntax:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">auto add = []&lt;typename T>(T a, T b) {return a + b;};<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>See also:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/www.modernescpp.com\/index.php\/more-powerful-lambdas-with-c-20\" target=\"_blank\" rel=\"noreferrer noopener\">More Powerful Lambdas with C++20<\/a><\/li><li><a href=\"https:\/\/www.fluentcpp.com\/2021\/12\/13\/the-evolutions-of-lambdas-in-c14-c17-and-c20\/\" target=\"_blank\" rel=\"noreferrer noopener\">The Evolutions of Lambdas in C++14, C++17 and C++20<\/a><\/li><li><a href=\"Lambdas: From C++11 to C++20, Part 1\">Lambdas: From C++11 to C++20, Part 1<\/a><\/li><li><a href=\"Lambdas: From C++11 to C++20, Part 2\">Lambdas: From C++11 to C++20, Part 2<\/a><\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">constexpr virtuals<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You heard it right: in C++20, virtual functions can be defined as constexpr:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">struct magic\n{\n    constexpr virtual int def() const { return 0; }\n};\n\nstruct programming_magic : public magic\n{\n    constexpr int def() const override { return 42; }\n};\n\nconstexpr int initval(magic const &amp; m)\n{\n    return m.def() + 1;\n}\n\nint main()\n{\n   constexpr programming_magic pm;\n   int arr[initval(pm)] = {0};\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This doesn&#8217;t seem to have too many use-cases. I don&#8217;t see where we can use this too much, but it&#8217;s now possible.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>See also:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/dev.to\/pgradot\/let-s-try-c-20-virtual-constexpr-functions-1m0e\" target=\"_blank\" rel=\"noreferrer noopener\">Let&#8217;s try C++20 | virtual constexpr functions<\/a><\/li><li><a href=\"https:\/\/www.cppstories.com\/2021\/constexpr-virtual\/\" target=\"_blank\" rel=\"noreferrer noopener\">C++20 Oxymoron: constexpr virtual<\/a><\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Coroutines<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This one is one of the major features of the C++20 standard. A coroutine is a function that has the ability to be suspended and resumed. Unfortunately, C++20 only defines a framework for the execution of coroutines, but does not define any coroutine types satisfying such requirements. That means, we need to either write our own or rely on 3rd party libraries for this. Such a library is the&nbsp;<a href=\"https:\/\/github.com\/lewissbaker\/cppcoro\/\" rel=\"noreferrer noopener\" target=\"_blank\">cppcoro<\/a>&nbsp;library.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In C++20, there are three new keywords, for coroutines: <code>co_await<\/code>, <code>co_return<\/code>, and <code>co_yield<\/code>. A function becomes a coroutine if it uses one of these three:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>the&nbsp;<code>co_await<\/code>&nbsp;operator to suspend execution until resumed<\/li><li>the&nbsp;<code>co_return<\/code>&nbsp;keyword to complete execution and optionally return a value<\/li><li>the&nbsp;<code>co_yield<\/code>&nbsp;keyword to suspend execution and return a value<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Here is an example of a producer-consumer scenario (a coroutine produces new values and another coroutine consumes them as they become available):<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;cppcoro\/generator.hpp>\n\ncppcoro::generator&lt;std::string> produce_items()\n{\n  while (true)\n  {\n     auto v = rand();\n     using namespace std::string_literals;\n     auto i = \"item \"s + std::to_string(v);\n     print_time();\n     std::cout &lt;&lt; \"produced \" &lt;&lt; i &lt;&lt; '\\n';\n     co_yield i;\n  }\n}<\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include &lt;cppcoro\/task.hpp>\n\ncppcoro::task&lt;> consume_items(int const n)\n{\n  int i = 1;\n  for(auto const&amp; s : produce_items())\n  {\n     print_time();\n     std::cout &lt;&lt; \"consumed \" &lt;&lt; s &lt;&lt; '\\n';\n     if (++i > n) break;\n  }\n\n  co_return;\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>See also:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/coroutines\" target=\"_blank\" rel=\"noreferrer noopener\">coroutines<\/a><\/li><li><a href=\"https:\/\/mariusbancila.ro\/blog\/2020\/06\/22\/a-cpp20-coroutine-example\/\" target=\"_blank\" rel=\"noreferrer noopener\">A C++20 coroutine example<\/a><\/li><li><a href=\"https:\/\/www.scs.stanford.edu\/~dm\/blog\/c++-coroutines.html\" target=\"_blank\" rel=\"noreferrer noopener\">My tutorial and take on C++20 coroutines<\/a><\/li><li><a href=\"https:\/\/www.modernescpp.com\/index.php\/implementing-futures-with-coroutines\" target=\"_blank\" rel=\"noreferrer noopener\">Implementing Simple Futures with Coroutines<\/a><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">That&#8217;s about it for the time being. If I missed anything important, please let me know.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2022\/01\/functions-1.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"687\" height=\"363\" src=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2022\/01\/functions-1.jpg\" alt=\"\" class=\"wp-image-4422\" srcset=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2022\/01\/functions-1.jpg 687w, https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2022\/01\/functions-1-300x159.jpg 300w\" sizes=\"auto, (max-width: 687px) 100vw, 687px\" \/><\/a><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>In programming, a function is a block of code that performs a computational task. (In practice, people write functions that perform many tasks, which is not very good, but it&#8217;s a topic beyond the purpose of this article). Functions are a fundamental concept of programming languages and C++ makes no exception. In fact, in C++ there is a large variety of functions that has evolved over time. In this article, I will give a brief walkthrough of this evolution starting with C++11. Since there are many things to talk about, I will not get into too many details on these topics but will provide various links for you to follow if you want to learn more.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","advgb_blocks_editor_width":"","advgb_blocks_columns_visual_guide":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[7],"tags":[451,345,513,475,632],"class_list":["post-4397","post","type-post","status-publish","format-standard","hentry","category-c","tag-c","tag-c11","tag-c14","tag-c17","tag-c23"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.4 - aioseo.com -->\n\t<meta name=\"description\" content=\"Learn about the evolution of functions in modern C++ with changes from C++11\/14\/17\/20. This article is a brief walkthrough the changes from the last decade.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Marius Bancila\"\/>\n\t<meta name=\"keywords\" content=\"c++,c++11,c++14,c++17,c++23\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/mariusbancila.ro\/blog\/2022\/01\/01\/the-evolution-of-functions-in-modern-cpp\/\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Marius Bancila&#039;s Blog | About code. Mostly on C++\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"The Evolution of Functions in Modern C++\" \/>\n\t\t<meta property=\"og:description\" content=\"Learn about the evolution of functions in modern C++ with changes from C++11\/14\/17\/20. This article is a brief walkthrough the changes from the last decade.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/mariusbancila.ro\/blog\/2022\/01\/01\/the-evolution-of-functions-in-modern-cpp\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2022-01-01T12:45:14+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2022-01-06T15:48:08+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"The Evolution of Functions in Modern C++\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Learn about the evolution of functions in modern C++ with changes from C++11\/14\/17\/20. This article is a brief walkthrough the changes from the last decade.\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/01\\\/01\\\/the-evolution-of-functions-in-modern-cpp\\\/#article\",\"name\":\"The Evolution of Functions in Modern C++\",\"headline\":\"The Evolution of Functions in Modern C++\",\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/01\\\/functions-1.jpg\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/01\\\/01\\\/the-evolution-of-functions-in-modern-cpp\\\/#articleImage\",\"width\":687,\"height\":363},\"datePublished\":\"2022-01-01T14:45:14+02:00\",\"dateModified\":\"2022-01-06T17:48:08+02:00\",\"inLanguage\":\"en-US\",\"commentCount\":2,\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/01\\\/01\\\/the-evolution-of-functions-in-modern-cpp\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/01\\\/01\\\/the-evolution-of-functions-in-modern-cpp\\\/#webpage\"},\"articleSection\":\"C++, C++, C++11, C++14, C++17, C++23\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/01\\\/01\\\/the-evolution-of-functions-in-modern-cpp\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"position\":2,\"name\":\"IT\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"position\":3,\"name\":\"Software\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"name\":\"C++\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"position\":4,\"name\":\"C++\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/01\\\/01\\\/the-evolution-of-functions-in-modern-cpp\\\/#listItem\",\"name\":\"The Evolution of Functions in Modern C++\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/01\\\/01\\\/the-evolution-of-functions-in-modern-cpp\\\/#listItem\",\"position\":5,\"name\":\"The Evolution of Functions in Modern C++\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/c\\\/#listItem\",\"name\":\"C++\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/\",\"name\":\"Marius Bancila\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/01\\\/01\\\/the-evolution-of-functions-in-modern-cpp\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Marius Bancila\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/01\\\/01\\\/the-evolution-of-functions-in-modern-cpp\\\/#webpage\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/01\\\/01\\\/the-evolution-of-functions-in-modern-cpp\\\/\",\"name\":\"The Evolution of Functions in Modern C++\",\"description\":\"Learn about the evolution of functions in modern C++ with changes from C++11\\\/14\\\/17\\\/20. This article is a brief walkthrough the changes from the last decade.\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2022\\\/01\\\/01\\\/the-evolution-of-functions-in-modern-cpp\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"datePublished\":\"2022-01-01T14:45:14+02:00\",\"dateModified\":\"2022-01-06T17:48:08+02:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"The Evolution of Functions in Modern C++","description":"Learn about the evolution of functions in modern C++ with changes from C++11\/14\/17\/20. This article is a brief walkthrough the changes from the last decade.","canonical_url":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/01\/the-evolution-of-functions-in-modern-cpp\/","robots":"max-image-preview:large","keywords":"c++,c++11,c++14,c++17,c++23","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/01\/the-evolution-of-functions-in-modern-cpp\/#article","name":"The Evolution of Functions in Modern C++","headline":"The Evolution of Functions in Modern C++","author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"},"image":{"@type":"ImageObject","url":"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2022\/01\/functions-1.jpg","@id":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/01\/the-evolution-of-functions-in-modern-cpp\/#articleImage","width":687,"height":363},"datePublished":"2022-01-01T14:45:14+02:00","dateModified":"2022-01-06T17:48:08+02:00","inLanguage":"en-US","commentCount":2,"mainEntityOfPage":{"@id":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/01\/the-evolution-of-functions-in-modern-cpp\/#webpage"},"isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/01\/the-evolution-of-functions-in-modern-cpp\/#webpage"},"articleSection":"C++, C++, C++11, C++14, C++17, C++23"},{"@type":"BreadcrumbList","@id":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/01\/the-evolution-of-functions-in-modern-cpp\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/#listItem","position":1,"name":"Home","item":"https:\/\/mariusbancila.ro\/blog\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","position":2,"name":"IT","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","position":3,"name":"Software","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","name":"C++"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","position":4,"name":"C++","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/01\/the-evolution-of-functions-in-modern-cpp\/#listItem","name":"The Evolution of Functions in Modern C++"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/01\/the-evolution-of-functions-in-modern-cpp\/#listItem","position":5,"name":"The Evolution of Functions in Modern C++","previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/#listItem","name":"C++"}}]},{"@type":"Organization","@id":"https:\/\/mariusbancila.ro\/blog\/#organization","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","url":"https:\/\/mariusbancila.ro\/blog\/"},{"@type":"Person","@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author","url":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/","name":"Marius Bancila","image":{"@type":"ImageObject","@id":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/01\/the-evolution-of-functions-in-modern-cpp\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g","width":96,"height":96,"caption":"Marius Bancila"}},{"@type":"WebPage","@id":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/01\/the-evolution-of-functions-in-modern-cpp\/#webpage","url":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/01\/the-evolution-of-functions-in-modern-cpp\/","name":"The Evolution of Functions in Modern C++","description":"Learn about the evolution of functions in modern C++ with changes from C++11\/14\/17\/20. This article is a brief walkthrough the changes from the last decade.","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/01\/the-evolution-of-functions-in-modern-cpp\/#breadcrumblist"},"author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"creator":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"datePublished":"2022-01-01T14:45:14+02:00","dateModified":"2022-01-06T17:48:08+02:00"},{"@type":"WebSite","@id":"https:\/\/mariusbancila.ro\/blog\/#website","url":"https:\/\/mariusbancila.ro\/blog\/","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","inLanguage":"en-US","publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"Marius Bancila's Blog | About code. Mostly on C++","og:type":"article","og:title":"The Evolution of Functions in Modern C++","og:description":"Learn about the evolution of functions in modern C++ with changes from C++11\/14\/17\/20. This article is a brief walkthrough the changes from the last decade.","og:url":"https:\/\/mariusbancila.ro\/blog\/2022\/01\/01\/the-evolution-of-functions-in-modern-cpp\/","article:published_time":"2022-01-01T12:45:14+00:00","article:modified_time":"2022-01-06T15:48:08+00:00","twitter:card":"summary","twitter:title":"The Evolution of Functions in Modern C++","twitter:description":"Learn about the evolution of functions in modern C++ with changes from C++11\/14\/17\/20. This article is a brief walkthrough the changes from the last decade."},"aioseo_meta_data":{"post_id":"4397","title":null,"description":"Learn about the evolution of functions in modern C++ with changes from C++11\/14\/17\/20. This article is a brief walkthrough the changes from the last decade.","keywords":[],"keyphrases":{"focus":[],"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":[],"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":{"id":"aioseo-article-63696513044ae","slug":"article","graphName":"Article","label":"Article","properties":{"type":"BlogPosting","name":"#post_title","headline":"#post_title","description":"#post_excerpt","image":"","keywords":"","author":{"name":"#author_name","url":"#author_url"},"dates":{"include":true,"datePublished":"","dateModified":""}}},"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":"{\"article\":{\"articleType\":\"BlogPosting\"},\"course\":{\"name\":\"\",\"description\":\"\",\"provider\":\"\"},\"faq\":{\"pages\":[]},\"product\":{\"reviews\":[]},\"recipe\":{\"ingredients\":[],\"instructions\":[],\"keywords\":[]},\"software\":{\"reviews\":[],\"operatingSystems\":[]},\"webPage\":{\"webPageType\":\"WebPage\"}}","pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":null,"created":"2021-12-28 17:13:34","updated":"2025-12-12 07:56:25","seo_analyzer_scan_date":null,"focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"author_meta":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"featured_img":null,"jetpack_publicize_connections":[],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"uagb_comment_info":2,"uagb_excerpt":"In programming, a function is a block of code that performs a computational task. (In practice, people write functions that perform many tasks, which is not very good, but it's a topic beyond the purpose of this article). Functions are a fundamental concept of programming languages and C++ makes no exception. In fact, in C++&hellip;","coauthors":[],"tax_additional":{"categories":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">C++<\/span>"]},"tags":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++11<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++14<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++17<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/c\/\" class=\"advgb-post-tax-term\">C++23<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">C++<\/span>","<span class=\"advgb-post-tax-term\">C++11<\/span>","<span class=\"advgb-post-tax-term\">C++14<\/span>","<span class=\"advgb-post-tax-term\">C++17<\/span>","<span class=\"advgb-post-tax-term\">C++23<\/span>"]}},"comment_count":"2","relative_dates":{"created":"Posted 5 years ago","modified":"Updated 5 years ago"},"absolute_dates":{"created":"Posted on January 1, 2022","modified":"Updated on January 6, 2022"},"absolute_dates_time":{"created":"Posted on January 1, 2022 2:45 pm","modified":"Updated on January 6, 2022 5:48 pm"},"featured_img_caption":"","series_order":"","jetpack_shortlink":"https:\/\/wp.me\/pYNdv-18V","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/4397","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/comments?post=4397"}],"version-history":[{"count":25,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/4397\/revisions"}],"predecessor-version":[{"id":4425,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/4397\/revisions\/4425"}],"wp:attachment":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/media?parent=4397"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/categories?post=4397"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/tags?post=4397"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}