gpt4 book ai didi

c++ - 如何将堆栈分配的多态指针数组模板化为接口(interface),包括派生类型的相应指针?

转载 作者:太空宇宙 更新时间:2023-11-03 17:26:10 26 4
gpt4 key购买 nike

就上下文而言,我正在研究嵌入式高可靠性环境。在这种环境中实现的一些限制包括:

  1. 没有动态内存分配
  2. 需要符合 c++14 或更低版本
  3. 没有运行时类型信息

所以最终结果是我想要一个包含 const std::array 的类BaseInterface 类型的指针,它可以包含一组分配给堆栈的任意派生类。

考虑下面的不完整示例。

注意:BaseHandler 构造函数,以及更多上下文问题的成员变量注释。

#include <array>
#include <tuple>
class BaseInterface {
public:
virtual void DoSomething() = 0;
};

class Derived1 : public BaseInterface {
void DoSomething() override {}
};
class Derived2 : public BaseInterface {
void DoSomething() override {}
};

/**
* @brief Handles stack allocated polymorphic arrays
*
* @tparam base_ptr_t pointer type that each element must derive from
* @tparam derived_t parameter pack of derived variables
*/
template <class base_ptr_t, class... derived_t>
class BaseHandler {
public:
BaseHandler(Elements &&... element)
: memory_store_x_{std::forward<derived_t>(element)...},
array_(/* How to make each elementwise pointer point to each element in the tuple/array of aligned_union?*/) {}
typedef std::array<base_ptr_t, sizeof...(Elements)> array_t;

const array_t GetArray();

private:
const array_t array_;
// Use tuple to store actual memory?
const std::tuple<Elements...> memory_store_0_;
// Use array of aligned_union's to store (perhaps memory inneficient compared
// to tuple) ??
std::array<std::aligned_union_t<0, derived_t...>, sizeof...(derived_t)>
memory_store_1_;
};

template <size_t N>
void Foo(const std::array<const BaseInterface *, N> &arr) {
// Do something interesting
}

int main() {
// Intended usage
BaseHandler<const BaseInterface *, Derived1, Derived2> handler(Derived1(),
Derived2());

auto arr = handler.GetArray();
Foo(arr);
}

我探索过但不喜欢的一些解决方法包括;

  1. 创建包含 static const std::array<X,X> 的功能性非通用辅助类/函数例如
const std::array<BaseInterface*,2> MakeResourceList() {
// Static lifetime, i.e. will not be destroyed when out of scope
static const Derived1 a();
static const Derived2 b();
std::array<BaseInterface*,2> result = {&a,&b};
return result;
}
  1. 构建所有资源并将它们手动传递到一个数组中。导致代码膨胀。
  2. 对所有构建的资源使用全局变量。

最佳答案

似乎您想将派生对象存储为元组,然后将该元组与将其转换为数组的函数应用:

template <class base_t, class... derived_t>
class BaseHandler {
static_assert(std::conjunction_v<std::is_base_of_v<base_t, derived_t>...>);
std::tuple<derived_t...> storage_;

public:
std::array<base_t*, sizeof...(derived_t)> GetArray() {
return std::apply([](derived_t&... deriveds){
return std:array<base_t*, sizeof...(derived_t)>{{&deriveds...}};
}, storage_);
}
};

为清楚起见,这使用 C++17 来处理一些库内容,但所有这些内容都可以在 C++14 中实现,没有任何问题。

我还将模板参数从 base_ptr_t 更改为 base_t 因为它使所有模板参数都具有相同的“类型”,而且您不必执行 remove_pointer_t 在静态断言中。

关于c++ - 如何将堆栈分配的多态指针数组模板化为接口(interface),包括派生类型的相应指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59727607/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com