Types of Fold Expressions in C++ 17
Last Updated :
11 Oct, 2023
Fold Expressions is a new feature of C++ 17, that allows us to create generic algorithms which can operate on any types and any number of inputs. They offer us a flexible, concise, and more efficient way to express what we’re trying to achieve with the code. In this article, we will discuss different types of Fold Expressions in C++17
Prerequisite: Fold Expression in C++
Types of Fold Expression
The fold expression can be classified into 4 types on the basis of the position of the parameter pack, operator and initial values. They are:
- Unary Left Fold
- Unary Right Fold
- Binary Left Fold
- Binary Right Fold
Let’s see each of them in detail.
1. Unary Left Fold Expressions
Unary Left Fold Expressions are those expressions in which the operators have left associativity i.e. while expanding the expression, the leftmost operator and operands will be evaluated first.
Syntax
(... pack op)
where
- pack: Parameter pack.
- op: Operator specifying the operation to be done.
The above expression can also be expanded as:
((pack1 op pack2) op ...) op packN
where N is the number of parameters in the parameter pack.
Example
C++
#include <iostream>
using namespace std;
template < typename ... Args>
auto diffFromLeft(Args... args)
{
return (... - args);
}
int main()
{
int result = diffFromLeft(2, 3, 5, 7);
cout << result << endl;
return 0;
}
|
Output
-13
Explanation
In the above program, the parameters were {2, 3, 5, 7}, and the fold expression used was (… – args) i.e. unary left fold expression. So, the expansion of the expression will be:
(((2 - 3) - 5) - 7)
which is -13.
2. Unary Right Fold Expression
The Unary Right Fold Expressions are opposite to the left fold expression i.e. they are right-associative. It means that the expression is evaluated from Right to Left.
Syntax
(pack op ...)
where
- pack: Parameter pack.
- op: Operator specifying the operation to be done.
The right fold expression will be expanded as:
(pack1 op (... op (packN-1 op packN)))
Example
C++
#include <iostream>
using namespace std;
template < typename ... Args>
auto diffFromRight(Args... args)
{
return (args - ...);
}
int main()
{
int result = diffFromRight(2, 3, 5, 7);
cout << result << endl;
return 0;
}
|
Output
-3
Explanation
The fold expression is (args – …) which is the right fold expression, so the expansion of the arguments {2, 3, 5, 7} will be different from the previous expression.
(2 - (3 - (5 - 7)))
which is -3.
3. Binary Left Fold Expression
Binary Left Fold Expressions have similar associativity as unary left-fold expressions i.e. left-to-right associativity but there is one more argument which is the initial value.
Syntax
(init op ... op pack)
where
- init: initial value of the given type.
- op: operator specifying the operation to be performed.
- pack: parameter pack
Note: The initial value is useful in cases to avoid errors where the parameter pack does not have any parameters.
Example
C++
#include <iostream>
using namespace std;
template < typename ... Args>
auto subtract(Args... args)
{
return (0 - ... - args);
}
int main()
{
cout << "Result With Arguments:" << subtract(2, 3, 5, 7)
<< endl;
cout << "Result Without Arguments: " << subtract()
<< endl;
return 0;
}
|
Result With Arguments:-17
Result Without Arguments: 0
Explanation
The expression is (0 – … – args) which is a binary left-fold expression. The expansion of the parameters {2, 3, 5, 7} will be similar to the unary left fold expression but there will be additional argument at the start.
((((0 - 2) - 3) - 5) - 7)
which is -17.
4. Binary Right Fold Expression
Binary right-fold expressions have RIGHT to LEFT Associativity and an additional argument – initial value.
Syntax
(args - ... - op)
where
- init: initial value of the given type.
- op: operator specifying the operation to be performed.
- pack: parameter pack
Example
C++
#include <iostream>
using namespace std;
template < typename ... Args>
auto diffFromRight(Args... args)
{
return (args - ... - 24);
}
int main()
{
cout << diffFromRight(2, 3, 5, 7) << endl;
return 0;
}
|
Output
21
Explanation
The expansion of the expression present in the article (binary right-fold expression) will be:
(2 - (3 - (5 - (7 - 21))))
Share your thoughts in the comments
Please Login to comment...