1
class Bar
{
Bar( var1 v1, var2 v2 )
    {
    // setup Bar fields
    }
// bar fields
}    

class Foo
{
Foo()
    :
    mArray();// how to do this part
    {

    }
std::array<Bar, 800> mArray;
}

I need to construct this array with some values using the ctor that bar provides that takes in some parameters, it's ok if they are all constructed to the same values because later I will assign them proper values I just have to get it initialized. I've googled this and tried many different syntax but for some reason I can't get it right.

EddieV223
  • 5,085
  • 11
  • 36
  • 38
  • This is a fixed array size, because I know the count of objects I'll need at compile time. – EddieV223 Jul 07 '13 at 17:17
  • Using initializer list will probably (since I haven't used it myself yet) do it: [SO link](http://stackoverflow.com/questions/6893700/how-to-construct-stdarray-object-with-initializer-list) – Tony Jul 07 '13 at 17:21

2 Answers2

3
template<unsigned...>struct seq {};
template<unsigned max, unsigned... s>struct make_seq:make_seq<max-1,max-1,s...>{};
template<unsigned...s>struct make_seq<0,s...>:seq<s...>{};

The above gives us compile time sequences.

We can then use it to generate a 800 element ctor to your array.

 template<unsigned N> Bar make_bar();
 template<unsigned N,unsigned...s>
 std::array<Bar,N> make_array_helper( seq<s...> ){
   return { make_bar<s>()... };
 }
 template<unsigned N>
 std::array<Bar,N> make_array(){
   return make_array_helper( make_seq<N>() );
 }

...which may contain typos (on phone), and you have to write make_bar, but it creates your array of 800 Bars for ya. The core of it is making a 800 element parameter pack then unpacking it to generate a 800 element constructor.

Altenatively add a default ctor to Bar.

Modifying this to take a single Barand making 800 copies is not hard either: all you need is to pass the Bar through to the final function, then use it to make the new element.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • In practice this won't work because it will exceed the recursive template instantiation limit for most compilers. If you really want to do it this way you'll need to use a logarithmic depth pattern as [shown here](http://stackoverflow.com/q/13072359/1131467). – Andrew Tomazos Jul 07 '13 at 19:07
  • @user1131467 At 800 it won't break the recommended recusion limit for C++11 (which is 900). I decided to keep it simple because it was small enough! – Yakk - Adam Nevraumont Jul 07 '13 at 21:43
  • Actually the recommended limit is 1024 not 900, but gccs default is 512 for some reason. No idea about clang or msvc. – Andrew Tomazos Jul 07 '13 at 22:03
1

The problem is that Bar doesn't have a default constructor, so std::array<Bar> doesn't have one either.

If you add a default constructor to Bar, std::array<Bar> will have one too:

#include <array>
using namespace std;

typedef int var1, var2;

class Bar
{
public:
Bar() {} // <--------- HERE

Bar( var1 v1, var2 v2 )
    {
    // setup Bar fields
    }
// bar fields
};    

class Foo
{
Foo()
    :
    mArray()
    {

    }
std::array<Bar, 3> mArray;
};
Andrew Tomazos
  • 66,139
  • 40
  • 186
  • 319
  • Am I expected to write out 800 bar ctors for the initializer list? – EddieV223 Jul 07 '13 at 17:26
  • it won't compile if Bar has no default(empty param) ctor – EddieV223 Jul 07 '13 at 17:29
  • @EddieV223: I just noticed Bar doesn't have a default constructor. That's the problem. – Andrew Tomazos Jul 07 '13 at 17:31
  • why can't we do something like array (Bar(arg,arg2,arg2)) ? Which would set up all the Bars to be equal to the Bar I sent in. – EddieV223 Jul 07 '13 at 17:31
  • @EddieV223: Because `std::array` doesn't offer such a constructor as it is an aggregate type. I would suggest using `std::vector` instead which does have such a constructor. `std::array` is a special type for performance-critical code - in almost all cases `std::vector` will be a better choice. – Andrew Tomazos Jul 07 '13 at 17:33
  • @user1131467, There's the fact that `std::array` can't change its size or anything. If it's not supposed to, it communicates that pretty clearly. – chris Jul 07 '13 at 17:46
  • @chris: One of the differences between `std::vector` and `std::array`, is that the size of the vector is a run-time variable, whereas the size of the array is a compile-time constant template parameter. Another difference is that array is an aggregate type, and a vector is not. – Andrew Tomazos Jul 07 '13 at 17:52
  • @user1131467, Yes, and when you want the compile-time aspect to be clear, `std::vector` doesn't communicate that effectively at all. – chris Jul 07 '13 at 18:08