At work I used this library some days ago and I find it amazingly useful:
Basically, boost::pfr lets you work with the fields of a given struct, as a std::tuple
, letting you access the elements through an index representing the position where the field is defined at inside the struct.
boost::pfr has also the benefit of being header-file-only and of not having any dependency with any other boost library, making it easy to install (copying its header files and that’s it) and use it.
Let’s see the example below. Suppose you have a struct Person
:
struct Person
{
std::string first_name;
std::string last_name;
int birth_year;
};
With boost::pfr, you can access any member in the struct given an index using a method called get()
that is very similar to its std::tuple
counterpart:
#include "boost/pfr.hpp"
int main()
{
Person composer { "Martin", "Gore", 1961};
auto& a = boost::pfr::get<0>(composer); // will return a std::string reference
auto& b = boost::pfr::get<1>(composer);
auto& c = boost::pfr::get<2>(composer); // will return a reference to the int field
std::cout << a << ", " << b << ", " << c << "\n";
return 0;
}
To get then number of elements in a struct, you have boost::pfr::tuple_size
:
int main()
{
std::cout << boost::pfr::tuple_size<Person>::value << "\n"; // returns 3 for our struct
}
To get the type of a given parameter, you have boost::pfr::tuple_element
:
int main()
{
boost::pfr::tuple_element<0, Person>::type s;
return 0;
}
In the example above, I declared a variable s
whose type is the same type of the element in the 0-th position in the struct Person
(i.e. a std::string
).
Use cases:
You could create a generic library to iterate through all the members of any struct and do something with each member (kind of std::for_each
[boost::pfr provides a for_each_field
function template to do this iteration] or std::visit
), for example, printing its values out (see my example below), saving them to disk, deserializing them or populating its values from a library (think of a SQL result set or a JSON object).
On printing a struct values out, boost::pfr already ships with a method called io_fields
that does exactly that:
int main()
{
Person singer { "Dave", "Gahan", 1962 };
std::cout << boost::pfr::io_fields(singer) << "\n";
}
This prints out “{ Dave, Gahan, 1962 }
“.
boost::pfr also ships with a lot of utilities to compare elements from a struct in other or to use any struct as a key on standard library maps and sets.
To learn more about this nice library, visit its documentation: https://apolukhin.github.io/pfr_non_boost/