[array] optional constructors in Boost.Array

I know that this subject has been discuss a lot in the past. However a quick search in the mailing list archive did not show any solution like the one I propose. If my post is a duplicate, please forgive :-) The problem is that, like many other, I don't use boost::array because it doesn't have any constructor. First, be aware that I want to start a flame war ;-) I understand well the rationale for the aggregate initialization support. I also understand that we want a lightweight wrapper around C arrays. I agree there is a consensus around this and I don't want to break it. However, I have a simple (I think) solution that should give us the best of both worlds. Basically, the idea is to have a third parameter to the template, it is set to false by default in order to provide the same default behaviour. So we have: template<class T, std::size_t N, bool C = false> class array { /* current implementation */ }; template<class T, std::size_t N> class array<T, N, true> : public array<T,N,false> { /* adds constructors only */ }; array<int, 3> a1 = { 1, 2, 3 }; array<int, 3, false> a2 = { 1, 2, 3 }; array<int, 3, true> a3; array<int, 3, true> a4( 1 ); // assign 1 to all three values array<int, 3, true> a5( 1, 2, 3 ); array<int, 3, true> a6( 1, 2 ); // raises a static assert because we try to put only two values in an array of 3 array<int, 3, true> a7( 1, 2, 3, 4 ); // also raises a static assert because we try to put four values in an array of 3 I only see one main drawback with this technique, we'll have some problems with compilers lacking partial specialization support. So the idea is in your hands. I hope it will have some echoes. I attached the modified array.hpp file. It compiles for me on Visual Studio .Net 2003 and 2005 with boost 1.33.1. However I didn't make full test coverage. Thanks Vincent Bherer-Roy

Sorry for the bad subject line... On 24-May-06, at 12:12, Vincent Bherer-Roy wrote:
I know that this subject has been discuss a lot in the past. However a quick search in the mailing list archive did not show any solution like the one I propose. If my post is a duplicate, please forgive :-)
The problem is that, like many other, I don't use boost::array because it doesn't have any constructor.
First, be aware that I want to start a flame war ;-) I understand well the rationale for the aggregate initialization support. I also understand that we want a lightweight wrapper around C arrays. I agree there is a consensus around this and I don't want to break it. However, I have a simple (I think) solution that should give us the best of both worlds.
Basically, the idea is to have a third parameter to the template, it is set to false by default in order to provide the same default behaviour. So we have:
template<class T, std::size_t N, bool C = false> class array { /* current implementation */ }; template<class T, std::size_t N> class array<T, N, true> : public array<T,N,false> { /* adds constructors only */ };
array<int, 3> a1 = { 1, 2, 3 }; array<int, 3, false> a2 = { 1, 2, 3 }; array<int, 3, true> a3; array<int, 3, true> a4( 1 ); // assign 1 to all three values array<int, 3, true> a5( 1, 2, 3 ); array<int, 3, true> a6( 1, 2 ); // raises a static assert because we try to put only two values in an array of 3 array<int, 3, true> a7( 1, 2, 3, 4 ); // also raises a static assert because we try to put four values in an array of 3
I only see one main drawback with this technique, we'll have some problems with compilers lacking partial specialization support.
So the idea is in your hands. I hope it will have some echoes.
I attached the modified array.hpp file. It compiles for me on Visual Studio .Net 2003 and 2005 with boost 1.33.1. However I didn't make full test coverage.
Thanks
Vincent Bherer-Roy
<array.hpp>

Vincent Bherer-Roy wrote:
I know that this subject has been discuss a lot in the past. However a quick search in the mailing list archive did not show any solution like the one I propose. If my post is a duplicate, please forgive :-)
The problem is that, like many other, I don't use boost::array because it doesn't have any constructor.
What is it specifically your are looking for? Maybe Boost.Assign can help you: http://www.boost.org/libs/assign/doc/index.html Look in particular for list_of() and cref_list_of(). -Thorsten

On 25-May-06, at 06:39, Thorsten Ottosen wrote:
What is it specifically your are looking for?
I'm basically looking for a way to initialize a Boost.Array. However, for me, the problem with this is larger, I want this class to be useful directly (without using another lib), safely (always initialized) and in the same way we use usual classes. I don't care about aggregates, as you can partially construct the object and officially only give compile time values. However I understand that some people like it and it is why I searched for a solution that let people use Boost.Array as an aggregate. But looking at old discussions, I pretty sure I'm not the only one who would like normal constructs for their arrays.
Maybe Boost.Assign can help you:
Ok, I was not aware that Boost.Assign works with Boost.Array sorry. This is good news and can help me thanks. However, I really prefer my solution. I think it is not to much invasive and it gives the user the usual construction syntax, which I think is something highly desirable. It gives an array concept closer to the STL container concept, by making array elements always initialized. And this without bugging too much those who wants to keep the Boost.Array as an aggregate. Also, it will gives compile time errors for things like that: array<int,4> a = list_of(1)(2)(3).to_array( a ); // compiles fine array<int,4, true> a(1,2,3); // doesn't compile array<int,4, true> a(1); // compile fine and repeats the value array<int,4, true> a(1,2,3,4); // compiles fine So, yes Boost.Assign can help, but no it is not what I was looking for ;-) -Vincent

Vincent Bhérer-Roy wrote:
On 25-May-06, at 06:39, Thorsten Ottosen wrote:
Maybe Boost.Assign can help you:
Ok, I was not aware that Boost.Assign works with Boost.Array sorry. This is good news and can help me thanks.
However, I really prefer my solution. I think it is not to much invasive and it gives the user the usual construction syntax, which I think is something highly desirable.
it would also break code that depends on the current number of template arguments.
It gives an array concept closer to the STL container concept, by making array elements always initialized. And this without bugging too much those who wants to keep the Boost.Array as an aggregate.
Maybe you should just wrap boost::array: template< class T, unsigned N > struct my_array : boost::array<T,N> { // provide constructors here }; -Thorsten

On 5/25/06, Thorsten Ottosen <thorsten.ottosen@dezide.com> wrote:
Maybe you should just wrap boost::array:
Yes this is the other solution, to offer a constructible_array. And surely I can do it on my own. But I think that this functionality should be in boost. I prefer my solution, because it is less wording, but I would prefer a constructible_array than nothing. -Vincent

Vincent Bhérer-Roy wrote:
On 25-May-06, at 06:39, Thorsten Ottosen wrote:
Also, it will gives compile time errors for things like that:
array<int,4> a = list_of(1)(2)(3).to_array( a ); // compiles fine
It should not be neccessary with to_array() on a conforming compiler.
array<int,4, true> a(1,2,3); // doesn't compile
Note that the former zero-initializes the remaining elements. -Thorsten

| -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of Thorsten Ottosen | Sent: 25 May 2006 15:02 | To: boost@lists.boost.org | Subject: Re: [boost] [array] optional constructors in Boost.Array | | Vincent Bhérer-Roy wrote: | > On 25-May-06, at 06:39, Thorsten Ottosen wrote: | | > Also, it will gives compile time errors for things like that: | > | > array<int,4> a = list_of(1)(2)(3).to_array( a ); // compiles fine | > array<int,4, true> a(1,2,3); // doesn't compile | | Note that the former zero-initializes the remaining elements. This is exactly what is NOT wanted. Although zeros are slightly better than a random not-initialised value, it is far, far better to get a compile time message when clearly one meant to initialize all the elements. This is a fundamental mistake in C philosophy IMO. It you want an array un-initialized, one should have say so very specifically. Otherwise, failure to initialize all the array is a mistake. (other languages have convenient syntax for repeat counts, but that another step). Paul --- Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539561830 & SMS, Mobile +44 7714 330204 & SMS pbristow@hetp.u-net.com

Paul A Bristow wrote:
| [mailto:boost-bounces@lists.boost.org] On Behalf Of Thorsten Ottosen
| > array<int,4> a = list_of(1)(2)(3).to_array( a ); // compiles fine | > array<int,4, true> a(1,2,3); // doesn't compile | | Note that the former zero-initializes the remaining elements.
This is exactly what is NOT wanted.
Although zeros are slightly better than a random not-initialised value, it is far, far better to get a compile time message when clearly one meant to initialize all the elements.
This is a fundamental mistake in C philosophy IMO.
It you want an array un-initialized, one should have say so very specifically.
OK, I see what you mean. I would be quite easy for me to let array<int, 5> = cref_list_of<6>(...); give a compile error if the dimensions did not match. It can also be done for list_of(), but it is much harder. Should I put this in the cvs for ref_list_of() and cref_list_of()? -Thorsten

On 5/25/06, Thorsten Ottosen <thorsten.ottosen@dezide.com > wrote:
OK, I see what you mean.
I would be quite easy for me to let
array<int, 5> = cref_list_of<6>(...);
give a compile error if the dimensions did not match.
It can also be done for list_of(), but it is much harder.
Should I put this in the cvs for ref_list_of() and cref_list_of()?
Sure! It would be a nice feture for Boost.Assign. However, it doesn't close the debate for me about a constructible array ;-) It is not that I don't like Boost.Assign or similar constructs, but I really think a good old constructor is far superior when available. So. Since people don't like my initial proposition, I then propose a "constructible_array" or another name that has the same behaviour than Boost.Array, except with construction. Any comments?

AlisdairM wrote:
Thorsten Ottosen wrote:
Note that the former zero-initializes the remaining elements.
Are you sure about that? I would have assumed value initialization, rather than zero initialization, although the former often results in the latter.
I think you're right. It does a[i] = value_type(); -Thorsten

| -----Original Message----- | From: boost-bounces@lists.boost.org | [mailto:boost-bounces@lists.boost.org] On Behalf Of AlisdairM | Sent: 25 May 2006 20:51 | To: boost@lists.boost.org | Subject: Re: [boost] [array] optional constructors in Boost.Array | | Thorsten Ottosen wrote: | | > Note that the former zero-initializes the remaining elements. | | Are you sure about that? | I would have assumed value initialization, rather than zero | initialization, although the former often results in the latter. If you two can't be sure about this without thought, then you two top experts have just proved the need for an explicit solution that novices won't have any doubts about either ;-)) Paul --- Paul A Bristow Prizet Farmhouse, Kendal, Cumbria UK LA8 8AB +44 1539561830 & SMS, Mobile +44 7714 330204 & SMS pbristow@hetp.u-net.com
participants (5)
-
AlisdairM
-
Paul A Bristow
-
Thorsten Ottosen
-
Vincent Bherer-Roy
-
Vincent Bhérer-Roy