Non-static Data Member Initializers / Calling constructors of std::vector

c++, c++11

Solution

Is there any hack I could use?

If your only goal is to not having to "explicitly" specify the type twice you could use `decltype` to provide some aid in your quest:

class Obj {
  std::vector<int> v1 = decltype(v1) (2,3);
};

Also remember that `typedef`/`using` is a great way of not having to type1 so much:

struct Obj {
   using VInt = std::vector<int>;
// typedef std::vector<int> VInt;

   VInt v = VInt (3,2);
};

1. pun not intended

What does the standard say about it?

Sadly the standard says the following about initializing members within the body of your class:

9.2/5 Class members [class.mem]

A member can be initialized using a brace-or-equal-initializer. (For static data members, see 9.4.2; for non-static data members, see 12.6.2).

We've already found a little hint about what is and what is not okay to do when initializing members, but to be 100% sure we should continue reading up on what a brace-or-equal-initializer really is.

8.5/1 Initializers [dcl.init]...

brace-or-equal-initializer:
      = initializer-clause
      braced-init-list

initializer-clause:
      assignment-expression
      braced-init-list

initializer-list:
      initializer-clause ...opt
      initializer-list , initializer-clause ...opt

braced-init-list:
      { initializer-list ,opt }
      { }

With the above specification of braced-or-equal-initializer we found that we are faced with two options when initializing members within the body of our class, using either a `=` together with an initializer-clause, or a `braced-init-list` on it's own.

The above boils down to either of these two:

struct Obj {
  Type foo = Type (1,2,3); /* example of an initializer-clause */
  Type bar        {1,2,3}; /* example of a  braced-init-list   */
};

braced-init-list looks awesome, let's use it!

Since `std::vector<...>` accepts a `std::initializer_list` in one overload of it's constructors we cannot use a braced-init-list to invoke the constructor taking two arguments `(size_type count, const T& value)`, because that will instead be used as the contents of our vector.

We are therefore stuck with using a initializer-clause.

See the previous hack for a confirming, but maybe not so obvious, solution.

Problem

Code: ``` class A { std::vector<int> x = {2,3}; // x[0] = 2 and x[1] = 3 std::vector<int> y = std::vector<int>(2,3); // x[0] = 3 and x[1] = 3 Too verbose!! }; ``` Is there a way that I can call the constructor of `std::vector<int>` only using brace initializer, or at least shorter version which gives the same effect? I don't want to repeat `std::vector<int>`.

Original source