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>`.