1

Is there a way to compose (or merge, aggregate) PODs between them ? One intuitive solution:

struct Base1 { int i; };
struct Base2 { char c; };

struct Derived : Base1, Base2 {};

// in a more generalized way
// template <class... Ts> struct Aggregate : Ts... {};

Except, we lose something:

int main()
{
    Derived d {42, 'c'}; // OK
    auto [i, c] = d; // Error
    static_assert(std::is_standard_layout_v<Derived>); // Error
}

I see we could end up with some ambiguousities, conflicts, between the merged base classes. But it would be pretty nice to merge PODs into one. The result I try to achieve:

struct Expected { int i; char c; }; // I want Derived to behave exactly like this

Am I in the realm of reflection? Should I end up using macros?

Arthur R.
  • 323
  • 2
  • 7
  • There are ways to get this to work by writing your own tuple access but the type you're making is [non-standard-layout](https://eel.is/c++draft/class#prop-3.7) – Mgetz Oct 15 '21 at 13:12
  • Did you want the resulting aggregate to also be a POD? – Eljay Oct 15 '21 at 13:25
  • @Eljay Actually I don't care if the derived struct is a POD or not, it takes the same size. I'd achieve the structured bindings feature at least. In a generic way if possible, i.e. for `template struct Aggregate : Ts... {};`. – Arthur R. Oct 15 '21 at 13:58

1 Answers1

1

If we

don't care if the derived struct is a POD or not

, the task is pretty simple with Boost.PFR - just convert your PODs to tuples and concatenate them:

template<typename... Ts> using Merge = decltype(std::tuple_cat(
    boost::pfr::structure_to_tuple(std::declval<Ts>())...
));

A simple test:

int main() {
    struct Base1 { int i, j; };
    struct Base2 { char c; };
    using Expected = Merge<Base1, Base2>;
    static_assert(std::is_same_v<Expected, std::tuple<int, int, char>>);
    Expected expected{42, 1337, 'c'};
    auto&& [i, j, c] = expected;
}
passing_through
  • 1,778
  • 12
  • 24