
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