Boost logo

Boost Users :

Subject: Re: [Boost-users] multi_array and variants
From: Alle Meije Wink (a.m.wink_at_[hidden])
Date: 2011-02-06 17:19:18


Dear All,

This is a problem that I wrote about 4+ months ago (and before that).
I know that many people struggle with it. How to make an array type
that can be 1,2,3, ... n-dimensional (for my specific problem n does
not need to be above 8)

First I hoped that a template definition for dimensionality (similar
to the type template) would be possible --it is not.

Then thanks to some great advice from this list I found a way to make
a sort-of generic class using boost::variant --not really generic as
it lists all the dimensionalities, but it should be able to use
generic visitors to handle addition, subtraction, etc.

I also found out that a default constructor is also always needed
--that was the last post on the subject, see below :).

But now, when I try to compile this to see if I'm on the right track,
my non-default constructor in which I specify the dimensionality d and
dimensions dims (a vector, or an extents[]) it complains that

||=== bis, Debug ===|
/home/amwink/programs/cpp/bis/include/bisArray.hpp|46|error: ‘d’ is not a type|
/home/amwink/programs/cpp/bis/include/bisArray.hpp|46|error: ‘dims’ is
not a type|
/home/amwink/programs/cpp/bis/src/bisArray.cpp|7|error: redefinition
of ‘class bis::bisArray<T, d, dims>’|
/home/amwink/programs/cpp/bis/include/bisArray.hpp|18|error: previous
definition of ‘class bis::bisArray<T, d, dims>’|
||=== Build finished: 4 errors, 0 warnings ===|

The attached code segment is basically as far as I got. I'm not sure
now if d and dims should be templated or not?

To be honest I can't see they they would not both work (in slightly
different ways)?

Anyone have a clue???
Many thanks!

Alle Meije

> Hi Alle,
>
> 2010/11/9 Alle Meije Wink <a.m.wink_at_[hidden]>
>
> > Dear Kris, thanks for your reply.
> >
>
> You are welcome.
>
> > > > template<typename T>
> > > > class bisArray: public bisObject {
> > > > typedef boost::variant
> > > > < boost::multi_array_ref<T, 1>,
> > > > boost::multi_array_ref<T, 2>,
> > > > boost::multi_array_ref<T, 3>,
> > > > boost::multi_array_ref<T, 4>,
> > > > boost::multi_array_ref<T, 5>,
> > > > boost::multi_array_ref<T, 6>,
> > > > boost::multi_array_ref<T, 7>,
> > > > boost::multi_array_ref<T, 8>,
> > > > boost::multi_array_ref<T, 9>
> > > > > bisArray_t;
> > > > bisArray_t _bisArray;
> >
>
> > However what I am stuck with seems to be, in essence, still the same thing:
> >
> > >>> /home/amwink/programs/cpp/bis/src/bisniftiimage.cpp||In function ‘void
> > bis::bisReadNifti(std::string)’:|
> > >>> /home/amwink/programs/cpp/bis/src/bisniftiimage.cpp|102|warning: unused
> > variable ‘testimage’|
> > >>> /usr/include/boost/variant/variant.hpp||In constructor
> > ‘boost::variant<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13,
> > T14, T15, T16, T17, T18, T19>::variant() [with T0_ =
> > boost::multi_array_ref<unsigned char, 1ul>, T1 =
> > boost::multi_array_ref<unsigned char, 2ul>, T2 =
> > boost::multi_array_ref<unsigned char, 3ul>, T3 =
> > boost::multi_array_ref<unsigned char, 4ul>, T4 =
> > boost::multi_array_ref<unsigned char, 5ul>, T5 =
> > boost::multi_array_ref<unsigned char, 6ul>, T6 =
> > boost::multi_array_ref<unsigned char, 7ul>, T7 =
> > boost::multi_array_ref<unsigned char, 8ul>, T8 =
> > boost::multi_array_ref<unsigned char, 9ul>, T9 =
> > boost::detail::variant::void_, T10 = boost::detail::variant::void_, T11 =
> > boost::detail::variant::void_, T12 = boost::detail::variant::void_, T13 =
> > boost::detail::variant::void_, T14 = boost::detail::variant::void_, T15 =
> > boost::detail::variant::void_, T16 = boost::detail::variant::void_, T17 =
> > boost::detail::variant::void_, T18 = boost::detail::variant::void_, T19 =
> > boost::detail::variant::void_]’:|
> > >>> /home/amwink/programs/cpp/bis/src/bisarray.hpp|52|instantiated from
> > ‘bis::bisArray<T>::bisArray(T*, size_t, std::vector<long unsigned int,
> > std::allocator<long unsigned int> >) [with T = unsigned char]’|
> > >>> /home/amwink/programs/cpp/bis/src/bisimage.hpp|33|instantiated from
> > ‘bis::bisImage<T>::bisImage(T*, size_t, std::vector<long unsigned int,
> > std::allocator<long unsigned int> >) [with T = unsigned char]’|
> > >>> /home/amwink/programs/cpp/bis/src/bisniftiimage.cpp|126|instantiated
> > from here|
> > >>> /usr/include/boost/variant/variant.hpp|1198|error: no matching function
> > for call to ‘boost::multi_array_ref<unsigned char, 1ul>::multi_array_ref()’|
> > >>> /usr/include/boost/multi_array/multi_array_ref.hpp|623|note: candidates
> > are: boost::multi_array_ref<T, NumDims>::multi_array_ref(T*, const typename
> > boost::const_multi_array_ref<T, NumDims, T*>::storage_order_type&, const
> > typename boost::const_multi_array_ref<T, NumDims, T*>::index*, const
> > typename boost::const_multi_array_ref<T, NumDims, T*>::size_type*) [with T =
> > unsigned char, long unsigned int NumDims = 1ul]|
> > >>> /usr/include/boost/multi_array/multi_array_ref.hpp|469|note:
> > boost::multi_array_ref<T, NumDims>::multi_array_ref(T*, const
> > boost::detail::multi_array::extent_gen<NumDims>&, const
> > boost::general_storage_order<NumDims>&) [with T = unsigned char, long
> > unsigned int NumDims = 1ul]|
> > >>> /usr/include/boost/multi_array/multi_array_ref.hpp|463|note:
> > boost::multi_array_ref<T, NumDims>::multi_array_ref(T*, const
> > boost::detail::multi_array::extent_gen<NumDims>&) [with T = unsigned char,
> > long unsigned int NumDims = 1ul]|
> > >>> /usr/include/boost/multi_array/multi_array_ref.hpp|417|note:
> > boost::multi_array_ref<unsigned char, 1ul>::multi_array_ref(const
> > boost::multi_array_ref<unsigned char, 1ul>&)|
> > >>> ||=== Build finished: 1 errors, 1 warnings ===|
> >
> > So boost.variant now sugegsts that multi_array_ref() is called, a
> > constructor with no arguments! I don't use that, and I don't even
> > think it exists (because it produces a multi_array view of an
> > *existing* C-style array!
> >
>
> The error sais, that the default constructor of multi_array_ref<uchar,1>
> (which does not exist) is being called from the default constructor of
> variant.
>
> By default, variant cannot be empty. It's default constructor tries to use
> the default constructor of the first type on the list. Therefore You have
> two options:
>
> 1) Always initialize the variant with some array,
> 2) Add a type to the beginning of the list, which will stand for "no value":
> #include <boost/none.hpp>
> variant< none_t, [...] > bisArray;
>
> Any idea why a problem with the *default* constructor would turn up?
> >
>
> The default ctor of each member is called if You don't specify another means
> of initialization in the constructor.
>
> Regards, Kris




Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net