Re: [Boost-users] multi_array and variants

Dear Kris, thanks for your reply.
What I now have is a class bisArray: ... template<typename T> class bisArray: public bisObject { typedef boost::variant < boost::multi_array_ref
, boost::multi_array_ref , boost::multi_array_ref , boost::multi_array_ref , boost::multi_array_ref , boost::multi_array_ref , boost::multi_array_ref , boost::multi_array_ref , boost::multi_array_ref bisArray_t; bisArray_t _bisArray; ...
and a class bisImage, which has a bisArray as well as a pointer to the data as read from file (1-dimensional structure): ...
template<typename T>
class bisImage: public bisObject {
public:
/** Constructor using existing array data Reformats array as bisImage */ bisImage ( T* _data, size_t _dimensions, std::vector
_sizes ): data(_data), dimensions(_dimensions) { This code (or You) comes from java or C#, doesn't it? ;-) In C++ it is supposed to be this->[...] instead of this.[...]
No, it's C (which doesn't use any of this -not properly at least). The whole this[...] business was not supposed to be there anyway I realised. The reason that I went to boost:: is that I was hoping to get one class for all data types (using T) and dimensionalities (using multi_array)
Second thing: the member storage is initialized with the default constructor (which in this case does not exist => error ), and then assigned (below).
I suggest a change to: bisImage([...]) : [...], storage( _data, _dimensions, _size ) { [...] and remove the assignment from the body of the constructor
Note also: I have read in many places, that you should not use names beginning with an underscore (_), because they are reserved for compiler/library implementation. One of those places was Herb Sutter's gotw series.
Ah! The underscore names come from a library that I tried to imitate which has successfully incorporated some aspects of boost(it is called MIMAS). Have not reached the stage of 'nicifying' the code yet... I moved the storage thing to where you suggested (1 line up) and that does get rid of lots of errors. 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
::variant() [with T0_ = boost::multi_array_ref , T1 = boost::multi_array_ref , T2 = boost::multi_array_ref , T3 = boost::multi_array_ref , T4 = boost::multi_array_ref , T5 = boost::multi_array_ref , T6 = boost::multi_array_ref , T7 = boost::multi_array_ref , T8 = boost::multi_array_ref , 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 ) [with T = unsigned char]’| /home/amwink/programs/cpp/bis/src/bisimage.hpp|33|instantiated from ‘bis::bisImage<T>::bisImage(T*, size_t, std::vector ) [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 ::multi_array_ref()’| /usr/include/boost/multi_array/multi_array_ref.hpp|623|note: candidates are: boost::multi_array_ref ::multi_array_ref(T*, const typename boost::const_multi_array_ref ::storage_order_type&, const typename boost::const_multi_array_ref ::index*, const typename boost::const_multi_array_ref ::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 ::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 ::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 ::multi_array_ref(const boost::multi_array_ref &)| ||=== 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 only way I knew to initialise a bisArray was with using a switch
statement -proper C:
switch dims{
case 1: _bisarray=multi_array_ref

Hi Alle,
2010/11/9 Alle Meije Wink
Dear Kris, thanks for your reply.
You are welcome.
template<typename T> class bisArray: public bisObject { typedef boost::variant < boost::multi_array_ref
, boost::multi_array_ref , boost::multi_array_ref , boost::multi_array_ref , boost::multi_array_ref , boost::multi_array_ref , boost::multi_array_ref , boost::multi_array_ref , boost::multi_array_ref 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
::variant() [with T0_ = boost::multi_array_ref , T1 = boost::multi_array_ref , T2 = boost::multi_array_ref , T3 = boost::multi_array_ref , T4 = boost::multi_array_ref , T5 = boost::multi_array_ref , T6 = boost::multi_array_ref , T7 = boost::multi_array_ref , T8 = boost::multi_array_ref , 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 ) [with T = unsigned char]’| /home/amwink/programs/cpp/bis/src/bisimage.hpp|33|instantiated from ‘bis::bisImage<T>::bisImage(T*, size_t, std::vector ) [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 ::multi_array_ref()’| /usr/include/boost/multi_array/multi_array_ref.hpp|623|note: candidates are: boost::multi_array_ref ::multi_array_ref(T*, const typename boost::const_multi_array_ref ::storage_order_type&, const typename boost::const_multi_array_ref ::index*, const typename boost::const_multi_array_ref ::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 ::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 ::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 ::multi_array_ref(const boost::multi_array_ref &)| ||=== 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
The default ctor of each member is called if You don't specify another means of initialization in the constructor. Regards, Kris

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
Hi Alle,
2010/11/9 Alle Meije Wink
Dear Kris, thanks for your reply.
You are welcome.
template<typename T> class bisArray: public bisObject { typedef boost::variant < boost::multi_array_ref
, boost::multi_array_ref , boost::multi_array_ref , boost::multi_array_ref , boost::multi_array_ref , boost::multi_array_ref , boost::multi_array_ref , boost::multi_array_ref , boost::multi_array_ref 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
::variant() [with T0_ = boost::multi_array_ref , T1 = boost::multi_array_ref , T2 = boost::multi_array_ref , T3 = boost::multi_array_ref , T4 = boost::multi_array_ref , T5 = boost::multi_array_ref , T6 = boost::multi_array_ref , T7 = boost::multi_array_ref , T8 = boost::multi_array_ref , 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 ) [with T = unsigned char]’| /home/amwink/programs/cpp/bis/src/bisimage.hpp|33|instantiated from ‘bis::bisImage<T>::bisImage(T*, size_t, std::vector ) [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 ::multi_array_ref()’| /usr/include/boost/multi_array/multi_array_ref.hpp|623|note: candidates are: boost::multi_array_ref ::multi_array_ref(T*, const typename boost::const_multi_array_ref ::storage_order_type&, const typename boost::const_multi_array_ref ::index*, const typename boost::const_multi_array_ref ::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 ::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 ::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 ::multi_array_ref(const boost::multi_array_ref &)| ||=== 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
(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
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

On 02/06/11 16:19, Alle Meije Wink wrote: [snip]
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
’| /home/amwink/programs/cpp/bis/include/bisArray.hpp|18|error: previous definition of ‘class bis::bisArray ’| ||=== 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? [snip] Hi Alle,
Unfortunately, the code which you attached does not contain the needed #includes. It would help us if you would provide a complete code example. However, the 'not a type' errors are because the in the CTOR: // initialising constructor bisArray(T, d, dims); the last 2 arguments: d, dims have to type. I assume you meant: // initialising constructor bisArray(T, size_t a_dim, size_t* a_extents); However, that's confusing me because that CTOR, I assume, is used toe create one of the variant components, and that, according to: http://www.boost.org/doc/libs/1_45_0/libs /multi_array/doc/reference.html#multi_array requires a compile-time value for NumDims, which, of course, the runtime value, a_dim, is not. So, it might help also if you provided the body of you CTOR also to help us see what you're trying to do. -regards, Larry
participants (3)
-
Alle Meije Wink
-
Krzysztof Czainski
-
Larry Evans