C ++ контейнер вопрос - PullRequest
4 голосов
/ 16 июля 2010

Я искал подходящий контейнер для 2D-элементов.То, что мне нужно, - это возможность перебирать каждый элемент контейнера с использованием, например, BOOST_FOREACH, и я также хотел бы иметь возможность создавать подпредставление (срезы / поддиапазоны) моего контейнера и, возможно, перебирать их тоже.

Прямо сейчас я использую boost::numeric::ublas::matrix для этих целей, но, ну, это не выглядит хорошим решением для меня, потому что, ну, это матрица BLAS, хотя она ведет себя очень хорошо, как обычныйКонтейнер 2-х элементов (пользовательские unbounded / bounded хранилища также очень хороши).

Другая альтернатива boost, boost::multi_array плохая, потому что вы не можете перебирать каждый элемент, используяодин оператор BOOST_FOREACH и потому что построение представлений имеет чрезвычайно запутанный синтаксис.

Любые альтернативы?

Спасибо.

Ответы [ 2 ]

1 голос
/ 16 июля 2010

Я делаю следующее (тип массива - концепция диапазона контейнера / итератора):

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_;
};
1 голос
/ 16 июля 2010

Определите свой собственный тип (тривиальный), предоставьте ему итератор и const_interator (тривиальный), и BOOST_FOREACH будет работать с ним.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...