pfr
pfr copied to clipboard
Type-based access
How about this sugar?
struct sample {
int first;
const char* second;
double third;
};
auto t = sample {1, "Foo", 3.14};
// index-based access
std::cout << "(" << boost::pfr::get<0>(t) << ", " << boost::pfr::get<1>(t)
<< ", " << boost::pfr::get<2>(t) << ")\n"; // Outputs: (1, Foo, 3.14)
// type-based access (Just like std::get after C++14)
std::cout << "(" << boost::pfr::get<int>(t) << ", " << boost::pfr::get<const char*>(t)
<< ", " << boost::pfr::get<double>(t) << ")\n"; // Outputs: (1, Foo, 3.14)
Looks good! PRs are welcomed!
What if there are two members of the same type?
What if there are two members of the same type?
I suppose in this case there should be a compilation error, as happens with std::get and std::tuple.
https://godbolt.org/z/zYKMzdv36
@apolukhin I'm thinking about a potential implementation, i.e. whether or not reference types stored in the tuple returned by tie_as_tuple could be analyzed or rather should the original ones defined in a struct be?
I'm asking because after tie the information about the references and cv-qualifiers can be lost/added so it's unclear to me what types would have to be passed into get. Consider e.g. (compiling in C++17):
struct sample
{
int first;
int& second;
double third;
};
int i = 1;
const volatile sample s = {0, i, 2.0};
decltype(auto) a = boost::pfr::get<0>(s); // const volatile int&
decltype(auto) b = boost::pfr::get<1>(s); // int&
decltype(auto) c = boost::pfr::get<2>(s); // const volatile double&
Btw, shouldn't the type of b be const volatile int& as well?
Are reference members supported? The following functions seems to return inconsistent tuples:
auto t0 = boost::pfr::detail::tie_as_tuple(s); // int const volatile&, int&, double const volatile&
auto t1 = boost::pfr::structure_tie(s); // int const volatile&, int const&, double const volatile&
auto t2 = boost::pfr::structure_to_tuple(s); // int, int, double
So if the implementation was based on tie_as_tuple with removed references and cv-qualifiers it'd work as if t2 was passed to get.
EDIT: I re-read the documentation and it seems that neither references nor const members are supported. Is this also true for volatile fields?
So AFAIU it should be enough to base the implementation on the type returned by tie_as_tuple.
@awulkiew
Is this also true for volatile fields?
It wasn't documented but I think this is also true for volatile because there is no supporting code to allow volatile(otherwise it code would be also for const and thus woundn't be such restrictions).
@apolukhin I think we should update the docs(add the note about volatile restriction).
Or maybe we can disable all const-volatile fields restrictions, at least for C++17. I started to discuss about it here: https://github.com/boostorg/pfr/issues/105