What's the latest on initialising arrays?

156 views
Skip to first unread message

Frederick Gotham

unread,
Jul 30, 2006, 1:03:48 AM7/30/06
to
What's the latest on adding array initialisation functionality to the
language? The following doesn't work if T doesn't have a public copy
constructor:

T array[] = { T(1), T(2), T(3), T(4), T(5) };

Here's some code I wrote today which initialises array members differently
-- I think you'll agree that it's unnecessarily complicated:

#include <new>
#include <iostream>

using std::cout;

#include <boost/type_traits/aligned_storage.hpp>
#include <boost/type_traits/alignment_of.hpp>

using boost::alignment_of;
using boost::aligned_storage;

class MyClass {
private:

int *const p;

MyClass(MyClass const &); /* Can't copy-construct! */

public:

MyClass(char const*) : p(new int)
{
cout << "Constructing!\n";
}

~MyClass()
{
delete p;

cout << "Destructing!\n";
}
};

int main()
{
aligned_storage<sizeof(MyClass)*5,
alignment_of<MyClass>::value> mem;

{
MyClass *p = reinterpret_cast<MyClass*>(&mem);

::new(p++) MyClass("a");
::new(p++) MyClass("b");
::new(p++) MyClass("c");
::new(p++) MyClass("d");
::new(p++) MyClass("e");
}

{
MyClass *p = reinterpret_cast<MyClass*>(&mem);

p++->~MyClass();
p++->~MyClass();
p++->~MyClass();
p++->~MyClass();
p++->~MyClass();
}
}

Considering all the functionality and features C++ has, this seems to be
quite a shortcoming.

--

Frederick Gotham

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std...@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Carl Barron

unread,
Jul 30, 2006, 3:35:40 PM7/30/06
to
Frederick Gotham <fgot...@SPAM.com> wrote:

Well this looks like it does the same thing and the same assumptions
as above and less tedious...

// create a fixed array of non_copyable objects.

template <class T,size_t N>
class Array
{
aligned_storage<sizeof(T)*N,alignment_of<T>::value >::type buffer;
T *p_T;
public:
template <class In>
Array(In bwgin)
{
p_T = reinterpret_cast<T *>(&buffer);
for(T *p=p_T;p!=p_T+N,++p,++begin)
::new(p) T(*begin);
}
~Array()
{
for(T *p=p_T;p!=p_T+N;++p)
p->~T();
}
T & operator [] (int n) {return p_T[n];}
};
// example.
int main()
{
const char **p = {"a","b","c","d","e";}
Array<MyClass,5> array(p);

Gene Bushuyev

unread,
Jul 30, 2006, 8:36:12 PM7/30/06
to
"Frederick Gotham" <fgot...@SPAM.com> wrote in message
news:SwMyg.12016$j7.3...@news.indigo.ie...

> What's the latest on adding array initialisation functionality to the
> language? The following doesn't work if T doesn't have a public copy
> constructor:
>
> T array[] = { T(1), T(2), T(3), T(4), T(5) };
>
[...]

> Considering all the functionality and features C++ has, this seems to be
> quite a shortcoming.

Arrays of noncopiable objects don't represent an interesting or useful concept
to deserve a special treatment from the Standard. You can as well define all the
members explicitly and not use array at all.

--
Gene Bushuyev (www.gbresearch.com)
----------------------------------------------------------------
To see what is in front of one's nose needs a constant struggle ~ George Orwell

skaller

unread,
Jul 31, 2006, 1:21:41 AM7/31/06
to
On Sun, 30 Jul 2006 05:03:48 +0000, Frederick Gotham wrote:

> What's the latest on adding array initialisation functionality to the
> language?

> Here's some code I wrote today which initialises array members differently

> -- I think you'll agree that it's unnecessarily complicated:

> int main()


> {
> aligned_storage<sizeof(MyClass)*5,
> alignment_of<MyClass>::value> mem;
>
> {
> MyClass *p = reinterpret_cast<MyClass*>(&mem);
>
> ::new(p++) MyClass("a");

[...]

> MyClass *p = reinterpret_cast<MyClass*>(&mem);
> p++->~MyClass();

[...]

> Considering all the functionality and features C++ has, this seems to be
> quite a shortcoming.

This is basically the same technique for getting around
the lack of unions of constructable types. In the case
of a stack emulation with nested structs and unions,
the emulation would be extremely messy .. your array
case is quite simple by comparison.

The main difference here is that you're actually allowed
to declare the array .. you just can't initialise it.

Your example:

T array[] = { T(1), T(2), T(3), T(4), T(5) };

may fail only if there's no copy constructor, but a slight modification
always fails:

struct X {
T array[5];
X(?? er, what to put in a ctor??
};

[Both cases are rescued if there is a default constructor and
assignment operator .. I'm assuming we don't want that].

So basically, at least a syntax for mem-initialisers
in classes would also be needed for arrays, for example:

X() : array ({ T(1), T(2), T(3), T(4), T(5) }) {}

suggests itself, and with that both cases might be solved
with some notion of direct (copy free) initialisation.

--
John Skaller <skaller at users dot sf dot net>
Try Felix, the successor to C++ http://felix.sf.net

Reply all
Reply to author
Forward
0 new messages