The C++17 standard was one of the major standards in the history of modern C++. One of the new library features in C++17 was std::apply
which is designed to be used with std::tuple
class template. In this post, we explain how to use apply with std::tuple
in C++ examples.
Table of Contents
What is std::tuple in C++?
The tuple
( std::tuple
) is a class template a fixed-size collection of different types of values like floats, integers, texts, etc. In another term tuple stores the different types of the elements, it also supports empty lists. This template is available since C++11 and improved in C++20 standards.
std::tuple
is a generalization of std::pair
. The destructor of tuple
is trivial if std::is_trivially_destructible<type>::value is set to true for every type in Types
.
Here is an example to define different types of members in a tuple, and printing out them,
1 2 3 4 5 6 7 |
std::tuple mycard { "12345687", "Yilmaz Yoru", 42}; std::cout << "ID:" << std::get<0>(mycard) << std::endl; std::cout << "Name:" << std::get<1>(mycard) << std::endl; std::cout << "Age:" << std::get<2>(mycard) << std::endl; |
and the output is,
1 2 3 4 5 |
ID:12345687 Name:Yilmaz Yoru Age:42 |
If you want to know more about std::tuple please check our posts below,
What is std::apply in C++?
The std::apply
(also called Tuple Apply) is a template defined in <tuple>
header that invokes a callable with arguments extracted from a given pair or tuple.
Syntax of std::apply since C++17 until C++23,
1 2 3 4 |
template<class _Func, class _Tuple> constexpr decltype(auto) apply(_Func&& _Fn, _Tuple&& _Tpl); |
Syntax of std::apply since C++23,
1 2 3 4 |
template< class _Func, tuple-like _Tuple > constexpr decltype(auto) apply( _Func&& func, _Tuple&& tuple ) noexcept(); |
How can we use std::apply with a function in C++?
We can use std::apply with functions. In this example we have a function that calculates area of a ring. We use std::make_pair() to define r1 and r2 pair.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#include <iostream> #include <tuple> #include <math.h> double myfunc(double r2, double r1) { return M_PI*(r2*r2-r1*r1); }; // area of a ring int main() { std::cout << "Ring Area :" << std::apply( myfunc, std::make_pair(20., 10.)) << std::endl; system("pause"); return 0; } |
Output will be as below,
1 2 3 |
Ring Area : 942.478 |
How can we use std::apply with a lambda definition in C++?
We can use std::apply with lambda definitions too. We use std::make_pair() to define r1 and r2 pair. Here is an example,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#include <iostream> #include <tuple> #include <math.h> auto mylambda = [](auto r2, auto r1) { return M_PI*(r2*r2-r1*r1); }; // area of a ring int main() { std::cout << "Ring Area : " << std::apply( mylambda, std::make_pair(20., 10.)) << std::endl; system("pause"); return 0; } |
Output will be as below,
1 2 3 |
Ring Area : 942.478 |
How can we use std::apply with tuple in C++ 17?
Now let’s use both function and lambda examples above with a tuple. Our tuple will be formed with two floating numbers that can be used as r2 and r1 parameters.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#include <iostream> #include <tuple> #include <cmath> double myfunc(double r2, double r1) { return M_PI*(r2*r2-r1*r1); }; auto mylambda = [](auto r2, auto r1) { return M_PI*(r2*r2-r1*r1); }; int main() { std::tuple mytuple { 20., 10. }; std::cout << "Ring Area : " << std::apply( myfunc, mytuple) << std::endl; std::cout << "Ring Area : " << std::apply( mylambda, mytuple) << std::endl; system("pause"); return 0; } |
Is there a full example about std::apply in C++ 17 and beyond?
Here is a full example of std::apply that is used with a function and lambda in the tuple of modern C++,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#include <iostream> #include <tuple> #include <cmath> double myfunc(double r2, double r1) { return M_PI*(r2*r2-r1*r1); }; auto mylambda = [](auto r2, auto r1) { return M_PI*(r2*r2-r1*r1); }; int main() { std::cout << "Ring Area : " << std::apply( myfunc, std::make_pair(20., 10.)) << std::endl; std::cout << "Ring Area : " << std::apply( mylambda, std::make_pair(20., 10.)) << std::endl; std::tuple mytuple { 20., 10. }; std::cout << "Ring Area : " << std::apply( myfunc, mytuple) << std::endl; std::cout << "Ring Area : " << std::apply( mylambda, mytuple) << std::endl; system("pause"); return 0; } |
Here is the output of full example about tuple apply,
1 2 3 4 5 6 |
Ring Area : 942.478 Ring Area : 942.478 Ring Area : 942.478 Ring Area : 942.478 |
For more details about this feature in C++17 standard, please see these papers; P0220R1
C++ Builder is the easiest and fastest C and C++ compiler and IDE for building simple or professional applications on the Windows operating system. It is also easy for beginners to learn with its wide range of samples, tutorials, help files, and LSP support for code. RAD Studio’s C++ Builder version comes with the award-winning VCL framework for high-performance native Windows apps and the powerful FireMonkey (FMX) framework for UIs.
There is a free C++ Builder Community Edition for students, beginners, and startups; it can be downloaded from here. For professional developers, there are Professional, Architect, or Enterprise versions of C++ Builder and there is a trial version you can download from here.