【问题标题】:"Merge" PODs into one将 POD“合并”为一个
【发布时间】:2021-12-03 16:30:45
【问题描述】:

有没有办法在它们之间组合(或合并、聚合)POD?一种直观的解决方案:

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

struct Derived : Base1, Base2 {};

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

除了,我们失去了一些东西:

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

我看到我们最终可能会在合并的基类之间产生一些歧义和冲突。但是将 POD 合并为一个会非常好。我试图达到的结果:

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

我在反思的领域吗?我应该最终使用宏吗?

【问题讨论】:

  • 有一些方法可以通过编写您自己的元组访问来使其工作,但您正在制作的类型是non-standard-layout
  • 您是否希望生成的聚合也成为 POD?
  • @Eljay 其实我不在乎派生的结构是否是 POD,它需要相同的大小。我至少会实现结构化绑定功能。如果可能,以通用方式,即template &lt;class... Ts&gt; struct Aggregate : Ts... {};。

标签: c++ inheritance reflection structured-bindings standard-layout


【解决方案1】:

如果我们

不管派生结构是否是 POD

,Boost.PFR 的任务非常简单 - 只需将您的 POD 转换为元组并将它们连接起来:

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

一个简单的测试:

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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-20
    • 2020-08-09
    • 2021-09-22
    • 2020-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多