To get n-th member of a struct without non-empty bases and w/o non-public members C++ now have a pretty way:#include <type_traits>#include <utility>#include <tuple>struct filler { template< typename type > operator type (); };template< typename aggregate, typename index_sequence = std::index_sequence<>, typename = void >struct aggregate_arity        : index_sequence{};template< typename aggregate, std::size_t ...indices >struct aggregate_arity< aggregate, std::index_sequence< indices... >, std::void_t< decltype(aggregate{(indices, std::declval< filler >())..., std::declval< filler >()}) > >    : aggregate_arity< aggregate, std::index_sequence< indices..., sizeof...(indices) > >{};template< std::size_t index, typename type >constexprdecltype(auto)get(type & value) noexcept{    constexpr std::size_t arity = aggregate_arity< std::remove_reference_t< std::remove_cv_t< type > > >::size();    if constexpr (arity == 1) {                auto & [p1] = value;        if constexpr (index == 0) {            return (p1);        } else {            return;        }    } else if constexpr (arity == 2) {        auto & [p1, p2] = value;        if constexpr (index == 0) {            return (p1);        } else if constexpr (index == 1) {            return (p2);        } else {            return;        }    } else if constexpr (arity == 3) {        auto & [p1, p2, p3] = value;        if constexpr (index == 0) {            return (p1);        } else if constexpr (index == 1) {            return (p2);        } else if constexpr (index == 2) {            return (p3);        } else {            return;        }    } else /* extend it by yourself for higher arities */  {        return;    }}#include <cstdlib>#include <cassert>intmain(){    using S = struct { int i; char c; bool b; };    S s{1, '2', true};    decltype(auto) i = get< 0 >(s);    decltype(auto) c = get< 1 >(s);    decltype(auto) b = get< 2 >(s);    static_assert(std::is_same< decltype(i), int & >{});    static_assert(std::is_same< decltype(c), char & >{});    static_assert(std::is_same< decltype(b), bool & >{});    assert(i == 1);    assert(c == '2');    assert(b == true);    s.i = 2;    s.c = '3';    s.b = false;    assert(i == 2);    assert(c == '3');    assert(b == false);    return EXIT_SUCCESS;}It is not as generic as one can want, but it is workable on clang from a current trunk.It also currently not works for top level cv-qualified class (due to clang bug) and can't properly forward referenceness of the input (though, it can be implemented for non-const references), but latter is hardly desired by anybody at all (maybe there would be conversion of referenceness from xvalue to prvalue, whereas lvalueness should be still preserved).What can I do it to improve the style and correcteness?Live example.
Get n-th data member of a struct
c++;reflection;c++17