c++ - 基于std::array的多维数组初始化

标签 c++

看到 std::array 的好处后,我尝试创建一个支持多维度的类。

我最初的实验使用了嵌套的 std::array。我选择不使用此方法的部分原因是编写类型的方式很丑。

即:std::array<std::array<std::array<...>, >, >

除了初始化之外,新类大部分都在工作。我还没有决定最好使用继承还是包含。选择可能取决于我是否可以进行初始化。

我怎样才能编译最后两行中的任何一行:

// multi-dimensional array based on std::array

#include <array>

template <class T, int s, int... r>
class arraynd_a : public std::array<arraynd_a<T, r...>, s>
{
public:
};

template <class T, int s>
class arraynd_a<T, s> : public std::array<T, s>
{
public:
};

template <class T, int s, int... r>
class arraynd_b
{
public:
    std::array<arraynd_b<T, r...>, s> arr;
};

template <class T, int s>
class arraynd_b<T, s>
{
public:
    std::array<T, s> arr;
};

void test()
{
    constexpr std::array<std::array<int, 2>, 3> a1 = { { { 0, 1 }, { 1, 0 }, { 2, 4 } } };
    /*constexpr*/ arraynd_a<int, 3, 2> a2a;
    /*constexpr*/ arraynd_b<int, 3, 2> a2b;
#if 0
    /*constexpr*/ arraynd_a<int, 3, 2> a3a =  { { { 0, 1 }, { 1, 0 }, { 2, 4 } } };
#endif
#if 0
    /*constexpr*/ arraynd_b<int, 3, 2> a3b =  { { { 0, 1 }, { 1, 0 }, { 2, 4 } } };
#endif
}

最佳答案

如果你正在做成员类的方式,你必须用 {} 再包装数组内容一次(你也不要用 std::array<int, 2> arr = 1, 2; 初始化数组,或者?):

template <class T, std::size_t DIM, std::size_t... ARGS>
struct arr_mult_dim
{
    std::array<arr_mult_dim<T, ARGS...>, DIM> arr_;
};
template <class T, int DIM>
struct arr_mult_dim<T, DIM>
{
    std::array<T, DIM> arr_;
};
template <class T, std::size_t... DIMS>
using arr_mult_dim_t = arr_mult_dim<T, DIMS...>;

然后像那样使用它:

arr_mult_dim_t<int, 2> arr_1 = { { 0, 1 } };

但是,如果您使用嵌套的 using 声明生成所需的类型,则更漂亮的方法是:

template <class T, std::size_t DIM, std::size_t... ARGS>
struct arr_mult_dim
{
    using type = std::array<typename arr_mult_dim<T, ARGS...>::type, DIM>;
};
template <class T, std::size_t DIM>
struct arr_mult_dim<T, DIM>
{
    using type = std::array<T, DIM>;
};
template <class T, std::size_t... DIMS>
using arr_mult_dim_t = typename arr_mult_dim<T, DIMS...>::type;

用法是:

arr_mult_dim_t<int, 2> arr_1 = { 0, 1 };
arr_mult_dim_t<int, 2, 2> arr_2 = { { { 0, 1 }, {0, 1} } };
arr_mult_dim_t<int, 2, 2, 2> arr_3 =
{
    {
        {
            {
                {0, 1 },
                { 0, 1 }
            }
        },
        {
            {
                { 0, 1 },
                { 0, 1 }
            }
        }
    }
};

现在您不需要使用额外的 {}。

编辑:我做了一些研究。我不知道为什么您的继承解决方案不起作用。从具有聚合属性的类继承的类也应该具有聚合属性。标准说:

The elements of an aggregate are: ...
- for a class, the direct base classes in declaration order followed by the direct non-static data members
in declaration order.

看起来这还没有实现。在旧标准中,有一个条款明确禁止聚合类具有基类:Why can I not brace initialize a struct derived from another struct?

关于c++ - 基于std::array的多维数组初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52309093/

相关文章:

c++ - 如何防止删除成员函数返回的指针?

python - 使用 Cython 在 C++ 的 Python 代码中使用数据

c++ - 数组分配问题

c++ - 具有 min()/max() 调用的代码出现奇怪的 C++ 错误

c++ - 在 C++ 中是否有任何统一的方法来创建自定义比较器?

c++ - 引用是否有存储位置?

c++ - 如何在 VS Coded UI Test Builder 的自定义控件中将测试提供程序从 MSAA 切换到 UIA

c++ - PCL-错误 C2039 : 'PointType' : is not a member of 'boost::shared_ptr<T>'

c++ - 定义(变量)没有被 MSVC 正确评估?

c++ - OpenCL 或 CUDA 调用的开销?