Re: [Boost-users] [multi_array] Feature request: constructor and resize from values
If an object does not have a default constructor what could it mean to have a block of memory holding one that has not been initialized? How would your program know if the object had been properly initialized or not? There are three ways to address this: 1 - A pointer, as already mentioned. A null pointer means the spot does not refer to ("contain") a valid object -- or any object at all. 2 - use a variant 3 - create a default constructor (which you could do by changing the signature of your constructor to something like (int = 0) or (int = -1) assuming those values are invalid). In all cases, regardless of semantics or implementation you'll either have to check at runtime for a valid object OR, if you know for other reasons which locations are valid, use the default constructor with any value you'd like. If you don't want to use pointers there are a couple of other possibilities:
Date: Sun, 22 Nov 2020 12:06:04 +0100 From: Eugenio Bargiacchi
mailto:svalorzen@gmail.com> Ah, sorry, I thought it would have been automatically clear. Consider this example:
class A { public: A(int) {} };
boost::multi_array array(boost::extents[2][2]); // Compiler error boost::multi_array array(boost::extents[2][2], A(3)); // What I would like
array.resize(boost::extents[2][2]); // Again, compiler error array.resize(boost::extents[2][2], A(2)); // What I would like
The variable `array` cannot be constructed in any way, as multi_array will try to default-construct it, and that will fail. Trying to simply create `array` with its default constructor works (although it will obviously be a zero-sized array), but when trying to resize it (to actually store things), the same thing will happen.
what could it mean to have a block of memory holding one that has not been initialized?
I am not proposing this. I am proposing to copy-construct elements, just as
std::vector does. Note that std::vector has the following constructor and
resize functions:
vector::vector( size_type count, const T& value = T ); // I am skipping
the allocator since it doesn't matter
void vector::resize( size_type count, const value_type& value );
Note how in both signatures there is an argument, value, that can take an
user-constructed value and simply copy it. Since the user has constructed
the value, it is well formed. This allows you to use std::vector with types
that are not default-constructible. This ofc requires the type to be
copy-constructible, but this can be a lesser restriction than not allowing
user-defined constructors in the first place. Again, the standard library
does this, so it's probably been motivated already.
I do not see a reason why multi_array could not do the same. In multi_array
case, the signature would be in the form:
multi_array(extents, const T & value);
resize(extents, const T & value);
I hope this clarifies what my request is. I do not want to use pointers, in
the same way that one would not recommend using pointers when storing
non-default-constructible classes in std::vector.
Best,
Eugenio Bargiacchi
On Wed, Nov 25, 2020 at 8:31 PM DV Henkel-Wallace
If an object does not have a default constructor what could it mean to have a block of memory holding one that has not been initialized? How would your program know if the object had been properly initialized or not?
There are three ways to address this:
1 - A pointer, as already mentioned. A null pointer means the spot does not refer to ("contain") a valid object -- or any object at all.
2 - use a variant
3 - create a default constructor (which you could do by changing the signature of your constructor to something like (int = 0) or (int = -1) assuming those values are invalid).
In all cases, regardless of semantics or implementation you'll either have to check at runtime for a valid object OR, if you know for other reasons which locations are valid, use the default constructor with any value you'd like.
If you don't want to use pointers there are a couple of other possibilities:
Date: Sun, 22 Nov 2020 12:06:04 +0100 From: Eugenio Bargiacchi
Ah, sorry, I thought it would have been automatically clear. Consider this example:
class A { public: A(int) {} };
boost::multi_array array(boost::extents[2][2]); // Compiler error boost::multi_array array(boost::extents[2][2], A(3)); // What I would like
array.resize(boost::extents[2][2]); // Again, compiler error array.resize(boost::extents[2][2], A(2)); // What I would like
The variable `array` cannot be constructed in any way, as multi_array will try to default-construct it, and that will fail. Trying to simply create `array` with its default constructor works (although it will obviously be a zero-sized array), but when trying to resize it (to actually store things), the same thing will happen.
participants (2)
-
DV Henkel-Wallace
-
Eugenio Bargiacchi