- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
在下面的代码中,ExtractSubArray
函数是完全通用的,而 ExtractSubArrayCornerAndExtent
需要在编写代码时了解维度(以构造RangeType 参数)。有什么方法可以编写通用的 ExtractSubArrayCornerAndExtent
(没有 SFINAE 为每个维度使用不同的函数(这会很烦人,并且需要一组固定的可能维度)。
#include <boost/multi_array.hpp>
template <unsigned int Dimension>
boost::multi_array<double, Dimension> ExtractSubArray(const boost::multi_array<double, Dimension>& array, const typename boost::detail::multi_array::index_gen<Dimension, Dimension>& indices)
{
using ArrayType = boost::multi_array<double, Dimension>;
using IndexType = boost::array<double, Dimension>;
typename ArrayType::template const_array_view<Dimension>::type view = array[indices];
IndexType subArraySize;
for(size_t dim = 0 ; dim < Dimension; ++dim) {
subArraySize[dim] = indices.ranges_[dim].finish_ - indices.ranges_[dim].start_;
}
ArrayType subArray = view;
return subArray;
}
template <unsigned int Dimension>
boost::multi_array<double, Dimension> ExtractSubArrayCornerAndExtent(const boost::multi_array<double, Dimension>& array, const boost::array<double, Dimension>& corner,
const boost::array<double, Dimension>& subarraySize)
{
using ArrayType = boost::multi_array<double, Dimension>;
using RangeType = typename ArrayType::index_range;
// Here I have assumed Dimension=3 to produce the second argument. How do you construct this second argument when you don't know Dimension ahead of time.
return ExtractSubArray<Dimension>(array, boost::indices[RangeType(corner[0],subarraySize[0])][RangeType(corner[1],subarraySize[1])][RangeType(corner[2],subarraySize[2])]);
}
int main()
{
using ArrayType = boost::multi_array<double, 3>;
using IndexType = boost::array<double, 3>;
ArrayType myArray(IndexType({{3,3,3}}));
std::vector<double> data(9);
for(size_t i = 0; i < data.size(); ++i) {
data[i] = i;
}
boost::detail::multi_array::index_gen<3,3> indices = boost::indices[ArrayType::index_range(0,1)][ArrayType::index_range(0,1)][ArrayType::index_range(0,1)];
ArrayType subArray = ExtractSubArray<3>(myArray, indices);
IndexType corner = {0,0,0};
IndexType subarraySize = {1,1,1};
ArrayType subArray2 = ExtractSubArrayCornerAndExtent<3>(myArray, corner, subarraySize);
return 0;
}
最佳答案
编译时迭代通常必须用递归来实现。您可以使用递归模板构建索引对象。它看起来像这样:
#include <boost/multi_array.hpp>
template <typename T, size_t Dimension>
boost::multi_array<T, Dimension> ExtractSubArray(
const boost::multi_array<T, Dimension>& array,
const typename boost::detail::multi_array::index_gen<Dimension, Dimension>& indices)
{
using ArrayType = boost::multi_array<T, Dimension>;
using IndexType = boost::array<size_t, Dimension>;
typename ArrayType::template const_array_view<Dimension>::type view = array[indices];
IndexType subArraySize;
for(size_t dim = 0 ; dim < Dimension; ++dim) {
subArraySize[dim] = indices.ranges_[dim].finish_ - indices.ranges_[dim].start_;
}
ArrayType subArray = view;
return subArray;
}
// Helper functor to build indices.
template<typename RangeArrayType, size_t Dimension>
struct IndicesBuilder {
// Recursively invoke the functor for the next lowest dimension and
// add the next range.
static auto build(const RangeArrayType& range)
-> decltype(IndicesBuilder<RangeArrayType, Dimension - 1>::build(range)[range[Dimension - 1]]) {
return IndicesBuilder<RangeArrayType, Dimension - 1>::build(range)[range[Dimension - 1]];
}
};
// Helper functor specialization to terminate recursion.
template<typename RangeArrayType>
struct IndicesBuilder<RangeArrayType, 1> {
static auto build(const RangeArrayType& range)
-> decltype(boost::indices[range[0]]) {
return boost::indices[range[0]];
}
};
template <typename T, size_t Dimension>
boost::multi_array<T, Dimension> ExtractSubArrayCornerAndExtent(
const boost::multi_array<T, Dimension>& array,
const boost::array<size_t, Dimension>& corner,
const boost::array<size_t, Dimension>& subarraySize)
{
using ArrayType = boost::multi_array<T, Dimension>;
using RangeType = typename ArrayType::index_range;
// Build a random-access container with the ranges.
std::vector<RangeType> range;
for (size_t i = 0; i < Dimension; ++i)
range.push_back(RangeType(corner[i], corner[i] + subarraySize[i]));
// Use the helper functor to build the index object.
const auto index = IndicesBuilder<decltype(range), Dimension>::build(range);
return ExtractSubArray<T, Dimension>(array, index);
}
int main() {
using ArrayType = boost::multi_array<double, 3>;
using IndexType = boost::array<size_t, 3>;
ArrayType myArray(IndexType({{3,3,3}}));
IndexType corner = {0,0,0};
IndexType subarraySize = {1,1,1};
ArrayType subArray2 = ExtractSubArrayCornerAndExtent(myArray, corner, subarraySize);
return 0;
};
添加到您的代码中的是 IndicesBuilder
模板结构,它具有用于构建索引对象的一维的静态函数。该静态函数调用自身(使用不同的模板参数)来构建所有维度。递归由返回第一个维度的 IndicesBuilder
的特化终止。尾随返回类型万岁!
我编译并运行了这段代码,没有出现 fatal error ,但我没有做任何进一步的测试,因此可能存在一些小错误。不过,一般方法应该可行。
关于c++ - 如何在运行时构建 multi_array::index_gen,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36501811/
我一直在研究 boost::multi_array 库,以寻找一个允许您在单个 for 循环中遍历整个 multi_array 的迭代器。 我不认为那个库中有任何这样的迭代器。 (在那里找到的迭代器可
我有一个 3 维的 boost::multi_array boost::multi_array* newArr = new boost::multi_array(boost::extents[x][
下面的代码给出了一个段错误: #include #include #include "binItr.h" #include using namespace std; int main(){
我面临以下问题。我想使用 boost::multi_array 创建一个对象指针的多维数组,但即使我编写的代码可以编译,当我尝试在 Eclipse 中运行时,程序也会终止并且不会打印任何内容。让我举例
我对我认为应该是一段简单的代码有疑问。我有一个 N x M 的二维数组,当前存储在 boost multi_array 中。 N 列表示空间维度,例如x,y,z 和 M 行是每个维度上的点。 我想做的
我有一个模板类,它执行一些计算并返回 multi_array,像这样有点过于简单了: template class C { public: typedef boost::multi_arra
我有三维 boost::multi_array 对象。我想将 origin 的绝对偏移量转换为多维索引,反之亦然。有没有一种简单的方法可以使用 boost 的内置工具来做到这一点,或者我需要自己根据数
我想学习如何将一个一维 multi_array 添加到另一个一维 multi_array 的末尾。我该怎么做? 最佳答案 与任何其他容器一样,Boost 多数组具有(没有很好记录的)迭代器,因此您可以
我正在使用 boost::multi_array 来存储一些数据。我使用 View 处理数据,因为我需要处理不同维度的数据切片。 我的问题是,boost::multi_array 的内存是如何管理的?
我正在使用二维 boost::multi_array 来存储自定义结构的对象。问题是我有大量的这些对象,所以我需要的数组索引超出了整数的范围。是否有可能将 long 用作多数组的索引,或者您对如何存储
我看过this post它解决了如何使用 boost::multi_array::origin() 函数循环遍历不是从零开始的数组,但这只会创建一个循环。 如何遍历multi_array的每一维,例如
范围可用于对 Boost 多维数组 (multi_array) 进行切片。根据documentation有多种定义范围的方法,但并非所有方法都能编译。我在 Ubuntu 11.04 上使用 GCC 4
假设我有一个 N 维 boost::multi_array(为简单起见,类型为 int),其中 N 在编译时已知,但可以变化(即是一个非类型模板参数).我们假设所有维度的大小都相同 m。 typede
首先我想说我是新手。 我正在尝试初始化 boost:multi_array在我的类(class)里。我知道如何创建 boost:multi_array : boost::multi_array foo
在下面的代码中,ExtractSubArray 函数是完全通用的,而 ExtractSubArrayCornerAndExtent 需要在编写代码时了解维度(以构造RangeType 参数)。有什么方
我有一个 3 维 boost::multi_array 表示 2d tilemaps 层。我希望能够清除一层——也就是遍历一层上的所有图 block 并将其值设置为 0,但我不知道该怎么做——我相信我
我正在尝试弄清楚 boost::multi_array 构造函数或调整大小方法是否可以抛出 bad_alloc 异常(或指示分配或调整大小失败的其他一些异常)。我无法在任何地方的文档中找到此信息。 澄
我必须通过引用或指针将数组传递给其他函数,我不在乎,只要它运行速度快即可。这就是我开始使用boost库的原因。我是通过以下方式做到的: using namespace boost; typedef
我无法调整 boost::multi_array 的大小。当我尝试它时,它会给出关于 std::_Copy_impl 等的错误。这是代码 #include typedef boost::multi_
我正在尝试使用以下测试程序将 boost::multi_array 的性能与本地动态分配的数组进行比较: #include #define _SCL_SECURE_NO_WARNINGS #defi
我是一名优秀的程序员,十分优秀!