【问题标题】:Array encapsulator that can work as fix-size (stack) AND dynamic-size (heap)可以用作固定大小(堆栈)和动态大小(堆)的数组封装器
【发布时间】:2017-06-24 04:38:55
【问题描述】:

昨天,我偶然发现了一个名为 Eigen 的库,它提供了 an array class,其签名如下:-

Array<float,Dynamic,1> b;//<--- dynamic = unknown at compile time
Array<float,3,1>       c;//<--- both row(=3) and col(=1) known at compile time

这里是Array.h和一个密切相关的类PlainObjectBase.h的源代码。

据我所知(通过挖掘),如果在编译时知道 row 和 col,它会将内存分配为 stack variable,与以下方式相同:-

float c[3];

我觉得很酷,因为它可以避免不必要的堆分配。
在某些情况下非常适合。

问题

什么是 C++ 技术/语义来创建支持固定和动态大小在 1 个类中的集合?

它背后的想法是什么?
我不是要完整的代码或任何 sn-p,但我不介意。

Answer 可以忽略所有关于 Eigen Array 是如何实现的事实。 (Eigen 只是一个例子。)

我想要一些可靠的想法来改进我自己的数组封装器,让它变得像那样酷。

我的糟糕解决方案

  • 为两种场景(动态和修复)创建字段,但在每个场景中,只使用其中的一部分。
  • 然后,发送垃圾邮件std::enable_if 来控制 Dynamic vs Const,但我认为这是反模式。

【问题讨论】:

  • 这是一个模板类,因此您可以使用 enable_if 和 is_arithmetic 来制作模板特化。这是一个示例:stackoverflow.com/questions/14294267/…
  • @Jerry Jeremiah 这是一个非常好的链接,谢谢。它实际上可能是一个答案。

标签: c++ arrays c++11 stack heap-memory


【解决方案1】:

他们通过部分专业化来做到这一点。基本上,Array 类模板将存储的创建委托给另一个类模板,该类模板部分专门用于他们命名为 Dynamic 的一些神奇值。

这是一个基本示例:

#include <memory>

constexpr int Dynamic = -1;

template <typename T, int N>
struct Storage
{
    Storage() : data{} {}
    T data[N];
};

template <typename T>
struct Storage<T, Dynamic>
{
    Storage(int count) : data{new T[count]} {}
    Storage() = delete;
    std::unique_ptr<T[]> data;
};


template <typename T, int N>
struct Array
{
    Array() : storage{} {}
    Array(int count) : storage{count} {}
    Storage<T, N> storage;
};


int main() {
    Array<int, 4> a1;
    //Array<int, 4> a2(10);  // Error since base Storage template has no constructor taking int.
    Array<int, Dynamic> a3(10);
    //Array<int, Dynamic> a4{};  // Error since Storage<T, Dynamic> has its default constructor deleted.
}

Live demo

基本上有两种不同的Storage 模板,一种用于N == Dynamic,另一种用于任何其他值。

事实上,如果您查看DenseStorage.h,您会看到与我的示例类似的模式。支持多维度和各种不同对齐的数据类型的专业化还有很多,但它们是同一个概念。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-05
    • 2015-05-05
    • 1970-01-01
    • 2015-12-11
    • 2023-04-10
    • 2021-03-15
    • 2021-03-26
    • 2011-03-22
    相关资源
    最近更新 更多