C++容器问题

发布于 2024-09-10 08:48:18 字数 473 浏览 1 评论 0原文

我一直在寻找一些合适的二维元素容器。我想要的是能够使用例如 BOOST_FOREACH 迭代容器的每个元素,并且我还希望能够构建容器的子视图(切片/子范围),并且可能进行迭代也通过他们。

现在我正在使用 boost::numeric::ublas::matrix 来实现这些目的,但是,它对我来说看起来不是一个好的解决方案,因为,它是一个 BLAS 矩阵,尽管它作为普通的 2d 元素容器表现得非常好(自定义无界 / 有界存储也非常好)。

另一种 boost 替代方案 boost::multi_array 很糟糕,因为您无法使用一个 BOOST_FOREACH 语句迭代每个元素,而且因为构造视图的语法极其混乱。

有其他选择吗?

谢谢。

I was looking for some suitable 2D element container. What I want is the ability to iterate through every element of the container using, for example BOOST_FOREACH and I also would like to have an ability to construct subview (slices / subranges) of my container and, probably iterate through them too.

Right now I am using boost::numeric::ublas::matrix for these purposes, but, well, it doesn't look as a good solution for me, because, well, it's a BLAS matrix, although it behaves very well as a plain 2d element container (custom unbounded / bounded storages are also very sweet).

Another boost alternative, boost::multi_array is bad, because you can't iterate through every element using one BOOST_FOREACH statement and because constructing views has extremely obfuscated syntax.

Any alternatives?

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一桥轻雨一伞开 2024-09-17 08:48:18

我执行以下操作(数组类型是容器/迭代器范围概念):

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_;
};

I do the following (array type is container/iterator range concept):

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

However, this will not work for slices: your best solution is to write an iterator for them.

Here is an example of using multi_array to provide storage of a custom class.
Perhaps you could do the same:

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_;
};
时间海 2024-09-17 08:48:18

定义您自己的类型(简单),给它一个迭代器和 const_interator(简单),BOOST_FOREACH 将使用它。

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

Define your own type (trivial), give it an iterator and const_interator (trivial), and BOOST_FOREACH will work with it.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文