2010-07-16 4 views
4

Je cherchais un conteneur d'éléments 2D approprié. Ce que je veux, c'est la capacité de parcourir tous les éléments du conteneur en utilisant, par exemple, BOOST_FOREACH et je voudrais également avoir la possibilité de construire des sous-vues (tranches/sous-limites) de mon conteneur et probablement les parcourir également.C++ conteneur question

Actuellement, j'utilise boost::numeric::ublas::matrix à ces fins, mais, bien, cela ne me semble pas une bonne solution, parce que, bien, c'est une matrice BLAS, bien qu'elle se comporte très bien comme un conteneur 2d simple élément (stock personnalisé unbounded/bounded sont également très doux).

Une autre boost alternative boost::multi_array est mauvais, parce que vous ne pouvez pas itérer chaque élément en utilisant une instruction BOOST_FOREACH et parce que la construction de points de vue a une syntaxe extrêmement brouillée.

Toute solution de rechange?

Merci.

+0

Je ne suis pas familier avec uBLAS, mais pourquoi ne pensez-vous pas l'utiliser est approprié? C'est un tableau 2d de ce que je peux dire. Le fait qu'il s'appelle une matrice ne signifie pas vraiment beaucoup. –

Répondre

1

Je fais ce qui suit (type tableau est un concept conteneur/plage iterator):

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

Cependant, cela ne fonctionnera pas pour les tranches: la meilleure solution est d'écrire un itérateur pour eux .

Voici un exemple d'utilisation de multi_array pour fournir le stockage d'une classe personnalisée. Peut-être vous pourriez faire la même chose:

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

Oui, je sais.Je veux dire que toute l'idée me semble erronée - utiliser 'ublas :: matrix' comme un simple conteneur 2d pour les éléments. C'est pourquoi je suis à la recherche de quelque chose de similaire et avec la même fonctionnalité en termes d'itération/subranging. –

+0

@Hard peut-être que vous pourriez cacher la matrice à l'intérieur de la classe personnalisée et contrôler quelles fonctionnalités vous exposer? bien, je ne vois rien de mal à utiliser la matrice juste un stockage. – Anycorn

1

Définissez votre propre type (trivial), donnez-lui un itérateur et un const_interator (trivial), et BOOST_FOREACH fonctionnera avec lui.

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

+1

Cela signifie que je suis en train de réinventer la roue et que je devrais aussi fournir le code pour le subrangement/la transformation/etc. Possible, mais je crois que de meilleures alternatives existent. –

+0

Vous ne réinventez pas la roue. Vous faites un itérateur. Cela devrait être un exercice trivial pour un développeur compétent. Si ce n'est pas trivial, alors c'est un bon exercice pour faire de vous un développeur plus compétent. De toute façon, vous gagnez. – corsiKa

+0

Vous avez ignoré la première étape: définissez votre propre type. S'il existe une bibliothèque 2d-array largement utilisée qui convient à ses besoins, alors c'est la définition précise de réinventer la roue. –