2010-07-16 62 views
4

我正在寻找一些合适的2D元素容器。我想要的是能够遍历容器的每个元素,例如BOOST_FOREACH,我也希望能够构建我的容器的子视图(切片/子范围),并且也可能遍历它们。C++容器问题

现在我正在使用boost::numeric::ublas::matrix用于这些目的,但是,它对我来说看起来并不是一个好的解决方案,因为它是BLAS矩阵,虽然它表现得非常好,就像一个普通的2d元素容器(自定义unbounded/bounded存储也非常甜)。

另一个boost替代,boost::multi_array是不好的,因为你无法通过使用一个BOOST_FOREACH声明的每一个元素和迭代,因为建设的意见具有极高混淆语法。

任何选择?

谢谢。

+0

我不熟悉ublas,但你为什么不觉得使用它是合适的?这是我可以告诉的二维数组。它被称为矩阵的事实并不意味着太多。 – 2010-07-16 16:07:18

回答

1

我做了以下(数组类型是容器/迭代器区间的概念):

ublas::matrix<douple> A; 
foreach (double & element, A.data()) 
{ 
} 

然而,这不适用于切片工作:你最好的解决办法是为他们写的迭代器。

以下是使用multi_array来提供自定义类的存储的示例。 也许你可以这样做:

template<size_t N, typename T> 
struct tensor_array : boost::multi_array_ref<T,N> { 
    typedef boost::multi_array_ref<T,N> base_type; 

    typedef T value_type; 
    typedef T& reference; 
    typedef const T& const_reference; 

    tensor_array() : base_type(NULL, extents()) 
    { 
     // std::cout << "create" << std::endl; 
    } 
    template<class A> 
    tensor_array(const A &dims) 
     : base_type(NULL, extents()) 
    { 
     //std::cout << "create" << std::endl; 
     resize(dims); 
    } 

    template<typename U> 
    void resize(const U (&dims)[N]) { 
     boost::array<U,N> dims_; 
     std::copy(dims, dims + N, dims_.begin()); 
     resize(dims_); 
    } 

    template<typename U> 
    void resize(const boost::array<U,N> &dims) { 
     size_t size = 1; 
     boost::array<size_t,N> shape; 
     for (size_t i = 0; i < N; ++i) { 
      size *= dims[i]; 
      shape[N-(i+1)] = dims[i]; 
     } 
     data_.clear(); 
     data_.resize(size, 0); 
     // update base_type parent 
     set_base_ptr(&data_[0]); 
     this->num_elements_ = size; 
     reshape(shape); 
    } 

    size_t size() const { return data_.size(); } 
    size_t size(size_t i) const { return this->shape()[N-(i+1)]; } 
    tensor_array& fill(const T &value) { 
     std::fill(data_.begin(), data_.end(), value); 
     return *this; 
    } 
private: 
    typedef boost::detail::multi_array::extent_gen<N> extents; 
    std::vector<T> data_; 
}; 
+0

是的,我知道。我的意思是像整个想法对我来说似乎是错误的 - 使用'ublas :: matrix'作为元素的简单2d容器。这就是为什么我在寻找类似的东西,并在迭代/子排列方面具有相同的功能。 – 2010-07-16 15:52:01

+0

@Hard也许你可以隐藏自定义类中的矩阵,并控制你暴露的功能?尽管如此,我发现使用矩阵只是一个存储没有什么不对。 – Anycorn 2010-07-16 15:57:13

1

定义你自己的类型(微不足道),给它一个迭代器和const_interator(平凡),并且BOOST_FOREACH将与它一起工作。

http://beta.boost.org/doc/libs/1_39_0/doc/html/foreach.html

+1

这意味着我正在重新发明轮子,并且我还必须提供代码以进行排列/转换/等等。可能的,但我相信有更好的替代方案存在。 – 2010-07-16 15:43:55

+0

你不是在重新发明轮子。你正在做一个迭代器。对于一个有能力的开发人员来说,这应该是一件小事。如果这不是微不足道的,那么让你成为一个更有能力的开发者是一个很好的练习。无论哪种方式,你赢了。 – corsiKa 2010-07-16 15:51:14

+0

您跳过第一步:定义您自己的类型。如果有一个广泛使用的二维阵列库适合他的需求,那么这就是重塑车轮的精确定义。 – 2010-07-16 16:00:15