C++中的可变维度动态数组
Variable dimension dynamic array in C++
我想在C++中实现一个类似 STL 的张量模板,它需要重载运算符 [] 来访问其元素,它可能看起来像这样:
Tensor<double,2> tensor2
{
{1,2,3},
{4,5,6}
};
std::cout<< tensor2[1][2]<<'n';
对于低尺寸,可能很容易使用一些类似的东西
std::vector<std::vector<int>>
但这在更高维度上并不容易使用。我还想在一个张量中实现张量之间的乘积和维度之间的收缩。
我用一些非常基本的操作实现了多维数组。由于 Boost.MultiArray 提供了更好的解决方案,我的实现仅用于演示。
namespace DataStructures
{
struct ExtentList //Discribe extents of dimensions for MultiArray
{
std::vector<size_t> dimensions;
ExtentList() = default;
template<typename Iterator, typename SFINAE = std::enable_if_t<std::_Is_iterator_v<Iterator>>>
ExtentList(Iterator begin, Iterator end) : dimensions(begin, end) {}
//operator[] used to initialize the extents
ExtentList& operator[](size_t n) { dimensions.push_back(n); return *this; }
ExtentList after_front() const { return ExtentList(++dimensions.cbegin(), dimensions.cend()); }
//at() used to access extents
size_t at(size_t n) const { return dimensions.at(n); }
};
static ExtentList Extents;
template<
typename ElemType, //Underlying Type
size_t Dimension, //Dimension of MultiArray
typename ElementAllocator = std::allocator<ElemType>, //Allocator for elements
template<typename, typename> typename ContainerType = std::vector, //Underlying container type
template<typename> typename ContainerAllocator = std::allocator> //Allocator for container
class MultiArray
{
//Necessary for contructor with ExtentList
friend class MultiArray<ElemType, Dimension + 1U, ElementAllocator, ContainerType, ContainerAllocator>;
using value_type = typename
std::conditional_t<
Dimension == 1U,
ElemType,
MultiArray<ElemType, Dimension - 1U, ElementAllocator, ContainerType, ContainerAllocator>>;
using allocator_type = typename
std::conditional_t<
Dimension == 1U,
ElementAllocator,
ContainerAllocator<value_type>>;
ContainerType<value_type, allocator_type> data;
public:
MultiArray() = default;
MultiArray(size_t n, const value_type& val) : data(n, val) {}
template<typename SFINAE = std::enable_if_t<(Dimension == 1U)>>
MultiArray(ExtentList extents, const ElemType& elem) : data(extents.at(0), elem) {}
template<typename SFINAE = std::enable_if_t<(Dimension >= 2U)>, typename SFINAE2 = SFINAE>
MultiArray(ExtentList extents, const ElemType& elem) : data(extents.at(0), value_type(extents.after_front(), elem)) {}
MultiArray(std::initializer_list<value_type> ilist) : data(ilist) {}
template<typename ... SizeType>
MultiArray(size_t N, SizeType... args) : data(N, value_type(args...)) {}
value_type& operator[](size_t n) { return data[n]; }
void push_back(const value_type& elem) { data.push_back(elem); }
};
}
这个想法是使用递归模板实现多维数组,因此允许订阅和列表初始化操作。
namespace DS = DataStructures;
DS::MultiArray<int, 2> matrix_2d
{
{ 1,2,3 },
{ 4,5,6 },
{ 7,8,9 }
};
for (size_t i = 0; i != 3; ++i)
for (size_t j = 0; j != 3; ++j)
std::cout << matrix_2d[i][j] << ' ';
DS::MultiArray<int, 3> matrix_3d(DS::Extents[10][10][10], 0);
size_t sum = 0;
for (size_t i = 0; i != DS::Extents.at(0); ++i)
for (size_t j = 0; j != DS::Extents.at(1); ++j)
for (size_t k = 0; k != DS::Extents.at(2); ++k)
sum += (matrix_3d[i][j][k] = i * 100 + j * 10 + k);
std::cout << sum << 'n' << matrix_3d[9][9][9] << 'n';
ExtentList 的想法来自 Boost。它比变量函数参数列表或变量模板更好。
相关文章:
- std::向量与传递值的动态数组
- 在c++中用vector填充一个简单的动态数组
- 输出没有重复元素的动态数组(收缩数组)C++
- 正在插入动态数组
- 如何在动态数组上使用搜索函数
- C++ 动态数组每次添加时将大小增加 1 - 错误
- 静态数组的自由动态数组
- 在 c++ 中对类中的 c 字符串动态数组进行排序的最佳方法是什么?
- 使用 thread 类在 C++ 中构造线程的动态数组时出错
- 如何为 c++ 的不同变量类型的结构元素创建动态数组?
- C++ 使用存储在动态数组中的文本文件中的数据查找模式
- 当我使用自定义类型创建动态数组时,即使使用字符串,它似乎也不起作用
- 为什么 c++ 动态数组的大小没有改变?
- 具有自定义构造函数 (C++) 的类型的动态数组分配
- 指针的 C++ 动态数组 - 何时需要使用它?
- 删除动态数组时未定义标识符
- 哈希映射使用 nullptr c++ 初始化节点的动态数组
- 如何将字符串和整数读取到两个单独的动态数组中的程序编写?
- 动态数组的 C++ 重载加运算符
- 基于数组的列表 - 动态数组创建时出错