Sign in to follow this  
Prune

Initializing member arrays of user-defined types without default constructors

Recommended Posts

I can initialize an array of a user defined type (without a default constructor, which is a necessity) with array<SomeClass, 5> = {1, 2, 3, 4, 5} However, I am unable to make this a class member because I can't figure out how to do that initialization in a constructor initializer list! What to do? Storing pointers to SomeClass instead is unacceptable due to this type being used in performance critical inner loops.

Share this post


Link to post
Share on other sites
Quote:
Original post by Prune
I can't figure out how to do that initialization in a constructor initializer list!

You can't! HAHAHAHA! Isn't C++ awesome?

Okay, okay, you can. array<Foo,2> asdf = { Foo(1), Foo(2) };.

Share this post


Link to post
Share on other sites
Quote:
Original post by Sneftel
Quote:
Original post by Prune
I can't figure out how to do that initialization in a constructor initializer list!

You can't! HAHAHAHA! Isn't C++ awesome?

Okay, okay, you can. array<Foo,2> asdf = { Foo(1), Foo(2) };.
What I wouldn't give for genuine array and struct literals, along with tuples... *sigh*

Share this post


Link to post
Share on other sites
You could use a helper function:

template<typename T, int N>
struct array
{
T data[N];
};

array<int, 3> make_array(int x, int y, int z)
{
array<int, 3> value = {x,y,z};

return value;
}

struct Foo
{
array<int, 3> member;

Foo() : member(make_array(1,2,3)) {}
};

int main()
{
Foo foo;
}


I have no idea how fast this might be.

Share this post


Link to post
Share on other sites
Quote:
Original post by Sneftel
Quote:
Original post by Prune
I can't figure out how to do that initialization in a constructor initializer list!

You can't! HAHAHAHA! Isn't C++ awesome?

Okay, okay, you can. array<Foo,2> asdf = { Foo(1), Foo(2) };.

asdf can't be a class member, as the syntax you used can neither be put in the declaration of asdf as a data member in the class, nor in the constructor. I think you didn't read my post correctly.

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
You could use a helper function:
*** Source Snippet Removed ***
I have no idea how fast this might be.


I could use a helper, but that's kind of ugly. Alternatively I could do a SomeClassArray type, which also is crappy as a solution.

I was looking at Furny's solution in http://www.gamedev.net/community/forums/topic.asp?topic_id=230443&PageSize=25&WhichPage=1 where he initializes a static array of pointers to members. However, this is initialized at compile time, whereas I need to initialize after an instantiation of the class containing SomeClass, because the argument I need to pass in the array initialization list is actually a pointer to a member of the containing class.
e.g.:

class SomeClass {... SomeClass(Foo *foo); ...} // No default constructor because SomeClass semantics make an instance invalid without a *foo

class Container {... Foo foo; ... array<SomeClass, 5> someClassArray; ...};

Container::Container(...) // How the hell to initialize someClassArray?

Maybe something like C++0x initializer_list would work but I don't know if that's implementable without compiler support beyond current C++ compilers.

This gets even worse if I need to load the size from a config file and have to allocate that array dynamically...

Share this post


Link to post
Share on other sites
Note support for this syntax is coming in C++0x.

You can generate an approximation of the syntax today.

Something like:
data(InitArray(1)(2)(3)(4)(5))
or
data(InitArray(data),1,2,3,4,5)
via operator overloading.

The idea is that the InitArray function creates an array initialization class. It overloads operator() or operator, in order to gather up the parameters. Each time it either returns an object of a different type (which keeps track of the nominal array size). Then finally it is implicitly cast into the type of your data variable (at which time it actually constructs the array in question).

Done right, you can even avoid doing any copying of the parameters more than the once.

If you have a limited number of parameters, you can use something like boost::tuple instead of an array.

Share this post


Link to post
Share on other sites
Quote:
Original post by NotAYakk
If you have a limited number of parameters, you can use something like boost::tuple instead of an array.


Or perhaps boost::assign would be of use? :)

Share this post


Link to post
Share on other sites
boost::assign looks like it just assigns, doesn't construct.
I'll try NotAYakk's solution, or just placement new individual objects into the array.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this