Skip to content

Latest commit

 

History

History
67 lines (48 loc) · 1.46 KB

350.md

File metadata and controls

67 lines (48 loc) · 1.46 KB
Info

Example

#include <tuple>

struct foo {
    int i{};
    bool b{};
    float f{};
};

constexpr auto f  = foo{.i = 42, .b = true, .f = 4.2f};
static_assert(42 == std::get<0>(f) and std::get<1>(f) and 4.2f == std::get<2>(f));

https://godbolt.org/z/r5vozndxb

Puzzle

  • Can you extend std::get to support aggregates?
#include <tuple>

struct foo {
    int i{};
    bool b{};
    float f{};
};

constexpr auto f  = foo{.i = 42, .b = true, .f = 4.2};
static_assert(42 == std::get<0>(f) and std::get<1>(f) and 4.2 == std::get<2>(f));

https://godbolt.org/z/MfWEcdh7s

Solutions

template <typename T, std::size_t I, typename = void>
struct has_get : std::false_type {};
template <typename T, std::size_t I>
struct has_get<T, I, std::void_t<decltype(std::get<I>(std::declval<T>()))>>
    : std::true_type {};

namespace std {
template <typename T>
concept DoesNotHaveGetConcept = requires(T t) { !has_get<T, 0>::value; };
namespace mp = boost::mp;
template <std::size_t I>
constexpr auto get(DoesNotHaveGetConcept auto s) {
    return std::get<I>(mp::reflection::to_tuple(s));
}
}  // namespace std

https://godbolt.org/z/WsTj1Tr79