Pregunta

We can initialise a boost or std::array using the following syntax:

array<int,5> b = {1, 2, 3, 4, 5};

This is fine if 'b' is a local variable. How about if 'b' is a class member?

b = {1, 2, 3, 4, 5}; // Error: expected an expression
b = array<int,5>{1, 2, 3, 4, 5}; // Error: type name is not allowed 
b = array<int,5>({1, 2, 3, 4, 5}); // Error: expected an expression
b = array<int,5>(1, 2, 3, 4, 5); // Error: no suitable constructor exists to convert from "int" to "array<int, 5>"

Do you really have to do this:

array<int,5> c = {1, 2, 3, 4, 5};

b = c;

Which seems a little wasteful as it creates 'c', initialises it, and then copies it into b before destroying 'c'.

¿Fue útil?

Solución 2

You can create them as in your question which will create a temporary on the stack and then copy it across to your instance (which may be a little wasteful), or you can use static variables and an initialisation list in which any compiler worth its salt will just initialise the appropriate members of the class:

class temp
{
   public:
   temp():b(b_default) {}
   array<int, 5> b;
   static array<int, 5> b_default;
};
array<int, 5> temp::b_default = {1,2,3,4,5};

This way is probably the 'cleanest' way however: (again, a single copy for all decent compilers)

class temp
{
   public:
   temp() 
   {
    static const array<int, 5> b_default = {1,2,3,4,5};

    b = b_default;
   }
   array<int, 5> b;
   static const array<int, 5> b_default;
};

Otros consejos

You can also initialize data members at the point of declaration:

struct Foo
{
  array<int,5> b = {1, 2, 3, 4, 5};
};

Alternatively, you can also use the constructor initialization list

struct Foo
{
  Foo() : b{1, 2, 3, 4, 5} {}
  array<int,5> b;
};

Note, all your statements involving b = X are not initializations, they are assignments.

Edit: This kind of initialization is not possible in C++03, but you could achieve something similar by calling a function that returns an suitable initialized array:

boost::array<int, 5> make_array()
{
  // trivial example, but you can do more complicated stuff here
  boost::array<int, 5> a = {{1, 2, 3, 4, 5}};
  return a;
}

then

Foo() : b(make_array()) {}

You may use the following:

struct S
{
  std::array<int, 5> b = {{1, 2, 3, 4, 5}};
};

Note the double {

Personnaly, I solve this kind of problem by creating my own initialization functions. Here, with preprocessor (in order to stay compatible with C++03), but it can be done with variadic templates (>= c++11).

#define NMAX_MAKE_ARRAY_PARAMETERS 30
#define MAKE_ARRAY_EDIT(z, n, data) \
  a__[n] = x__ ## n;
#define MAKE_ARRAY_DEFINITION(z, n, data) \
  template <typename T> boost::array<T,n> make_array(BOOST_PP_ENUM_PARAMS(n, const T& x__)) \
  { \
    boost::array<T,n> a__; \
    BOOST_PP_REPEAT(n, MAKE_ARRAY_EDIT, 0) \
    return a__; \
  }
#define MAKE_ARRAY_DEFINITIONS(n) \
  BOOST_PP_REPEAT(BOOST_PP_INC(n), MAKE_ARRAY_DEFINITION, 0)
MAKE_ARRAY_DEFINITIONS(NMAX_MAKE_ARRAY_PARAMETERS)

With this code included, I can easily create arrays having size between 0 and 30 :

boost::array<double,5> a = make_array<double>(1.0, 2.2, 3.4, 4.6, 5.8);
a = make_array<double>(0.0, 0.1, 0.2, 0.3, 0.4);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top