C++
Raiting:
42

Look at the interesting innovations in C++17 with examples


C++ language is constantly evolving, and for us, as for developers of a static analyzer, it is important to track all its changes, in order to support all new features of the language. In this review article, I would like to share with the reader the most interesting innovations introduced in C++17, and demonstrate them with examples.

image

Now, developers of compilers are actively adding support for the new standard.

Fold expressions

I would like to start with a few words about what a fold is (also known as reduce or accumulate).
Fold is a function that applies the assigned combining function to sequential pairs of elements in a list, and returns a result. The simplest example is the summing up of elements in the list using a fold:

Example from C++:


std::vector<int> lst = { 1, 3, 5, 7 };
int res = std::accumulate(lst.begin(), lst.end(), 0,
[](int a, int b) { return a + b; });
std::cout << res << '\n'; // 16

If the combining function is applied to the first item in a list and to the result of the recursive processing of the tail of a list, then the fold is called 'right'. In our example, we will get:

1 + (3 + (5 + (7 + 0)))
If the combining function is applied to the result of the recursive processing at the top of the list (the entire list without the last element) and to the last element, then a folding is called 'left'. In our example, we will get:

(((0 + 1) + 3) + 5) + 7
Thus, the fold type determines the order of evaluation.

In C++17 there is also folding support for a template parameters list. It has the following syntax:
(pack op ...) A unary right associative fold
(... op pack) A unary left associative fold
(pack op ... op init) A binary right associative fold
(init op ... op pack) A binary left associative fold

op is one of the following binary operators:


+ - * / % ^ & | ~ = < > << >> += -= *= /= %=
^= &= |= <<= >>= == != <= >= && || , .* ->*

pack is an expression containing an undisclosed parameter pack

init - initial value

For example, here's a template function that takes a variable number of parameters and
calculates their sum:


// C++17
#include <iostream>

template<typename... Args>
auto Sum(Args... args)
{
return (args + ...);
}

int main()
{
std::cout << Sum(1, 2, 3, 4, 5) << '\n'; // 15
return 0;
}

Note: In this example, the Sum function could be also declared as constexpr.
If we want to specify an initial value, we can use binary fold:


// C++17
#include <iostream>

template<typename... Args>
auto Func(Args... args)
{
return (args + ... + 100);
}

int main()
{
std::cout << Func(1, 2, 3, 4, 5) << '\n'; //115
return 0;
}

Before C++17, to implement a similar function, you would have to explicitly specify the rules for recursion:


// C++14
#include <iostream>

auto Sum()
{
return 0;
}

template<typename Arg, typename... Args>
auto Sum(Arg first, Args... rest)
{
return first + Sum(rest...);
}

int main()
{
std::cout << Sum(1, 2, 3, 4); // 10
return 0;
}

It is worth highlighting the operator ',' (comma), which will expand the pack into a sequence of actions separated by commas. Example:


// C++17
#include <iostream>

template<typename T, typename... Args>
void PushToVector(std::vector<T>& v, Args&&... args)
{
(v.push_back(std::forward<Args>(args)), ...);

//This code is expanded into a sequence of expressions
//separated by commas as follows:
//v.push_back(std::forward<Args_1>(arg1)),
//v.push_back(std::forward<Args_2>(arg2)),
//....
}

int main()
{
std::vector<int> vct;
PushToVector(vct, 1, 4, 5, 8);
return 0;
}

Thus, folding greatly simplifies work with variadic templates.
Kate Milovidova 13 october 2017, 14:23
Vote for this post
Bring it to the Main Page
 

Comments

Leave a Reply

B
I
U
S
Help
Avaible tags
  • <b>...</b>highlighting important text on the page in bold
  • <i>..</i>highlighting important text on the page in italic
  • <u>...</u>allocated with tag <u> text shownas underlined
  • <s>...</s>allocated with tag <s> text shown as strikethrough
  • <sup>...</sup>, <sub>...</sub>text in the tag <sup> appears as a superscript, <sub> - subscript
  • <blockquote>...</blockquote>For  highlight citation, use the tag <blockquote>
  • <code lang="lang">...</code>highlighting the program code (supported by bash, cpp, cs, css, xml, html, java, javascript, lisp, lua, php, perl, python, ruby, sql, scala, text)
  • <a href="http://...">...</a>link, specify the desired Internet address in the href attribute
  • <img src="http://..." alt="text" />specify the full path of image in the src attribute