[multi_array] Feature request: constructor and resize from values

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[multi_array] Feature request: constructor and resize from values

Boost - Users mailing list
I'd love to be able to use multi_array with classes that do not have a default constructor. At the moment, this is impossible, as both the constructor and resize functions only take extents as arguments (and possibly some other options), but no value_type, as for example std::vector does. Thus, trying to store objects without a default constructor in a multi_array results in hard compiler errors, with no workaround that I know of.

This happens to me fairly often, as I use multi_array to organize sets of complex objects. If there is a technical reason why this is not possible, I would also be happy to learn it.

Best regards,
Eugenio Bargiacchi

_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [multi_array] Feature request: constructor and resize from values

Boost - Users mailing list
As you don't give any example, I can't know exactly what you want to do. But how about using multi_array to store pointers? Then you can construct your objects at any time.

On Fri, Nov 20, 2020 at 11:55 PM Eugenio Bargiacchi via Boost-users <[hidden email]> wrote:
I'd love to be able to use multi_array with classes that do not have a default constructor. At the moment, this is impossible, as both the constructor and resize functions only take extents as arguments (and possibly some other options), but no value_type, as for example std::vector does. Thus, trying to store objects without a default constructor in a multi_array results in hard compiler errors, with no workaround that I know of.

This happens to me fairly often, as I use multi_array to organize sets of complex objects. If there is a technical reason why this is not possible, I would also be happy to learn it.

Best regards,
Eugenio Bargiacchi
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users

_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [multi_array] Feature request: constructor and resize from values

Boost - Users mailing list
Ah, sorry, I thought it would have been automatically clear. Consider this example:

class A {
    public:
        A(int) {}
};

boost::multi_array<A,2> array(boost::extents[2][2]); // Compiler error
boost::multi_array<A,2> 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.

Using pointers could work, but it's simply not viable, as it requires me to do memory management manually. I simply do not wish to do so, and it kind of runs contrary to modern C++ practices. I could use `unique_ptr`, but it feels more convoluted than it should be (along with requiring an additional layer of unneeded indirection). I feel multi_array should be capable of being constructed from existing values, just as `std::vector` and other standard containers can do.

Would this be possible?

On Sun, Nov 22, 2020 at 6:07 AM kila suelika via Boost-users <[hidden email]> wrote:
As you don't give any example, I can't know exactly what you want to do. But how about using multi_array to store pointers? Then you can construct your objects at any time.

On Fri, Nov 20, 2020 at 11:55 PM Eugenio Bargiacchi via Boost-users <[hidden email]> wrote:
I'd love to be able to use multi_array with classes that do not have a default constructor. At the moment, this is impossible, as both the constructor and resize functions only take extents as arguments (and possibly some other options), but no value_type, as for example std::vector does. Thus, trying to store objects without a default constructor in a multi_array results in hard compiler errors, with no workaround that I know of.

This happens to me fairly often, as I use multi_array to organize sets of complex objects. If there is a technical reason why this is not possible, I would also be happy to learn it.

Best regards,
Eugenio Bargiacchi
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users

_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [multi_array] Feature request: constructor and resize from values

Boost - Users mailing list
In reply to this post by Boost - Users mailing list
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 <[hidden email]>

Ah, sorry, I thought it would have been automatically clear. Consider this
example:

class A {
   public:
       A(int) {}
};

boost::multi_array<A,2> array(boost::extents[2][2]); // Compiler error
boost::multi_array<A,2> 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.


_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [multi_array] Feature request: constructor and resize from values

Boost - Users mailing list
> 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 <[hidden email]> wrote:
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 <[hidden email]>

Ah, sorry, I thought it would have been automatically clear. Consider this
example:

class A {
   public:
       A(int) {}
};

boost::multi_array<A,2> array(boost::extents[2][2]); // Compiler error
boost::multi_array<A,2> 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.


_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users