3

When using std::vector's fill constructor (either form) with C++11's class member initialization feature, the following code fails to compile (under clang/llvm 3.6):

#include <vector>

class Foo
{
  std::vector<char> buf_(10); //compiler error!
  std::vector<std::vector<char>> buf2_(10, std::vector<char>(20)); //compiler error!

public:
  void Bar();
};

void Foo::Bar()
{
  std::vector<char> buf3_(10); //OK
  std::vector<std::vector<char>> buf4_(10, std::vector<char>(20));  //OK
}

I've searched for issues around vector fill constructors and class member initialization, but have come up empty. Any idea what am I missing?

U007D
  • 5,772
  • 2
  • 38
  • 44

2 Answers2

7

In-place initialization of non-static data members is not allowed using that syntax. You need the form

T t{args}; // 1

or

T = t{args}; // 2

or

T = t(args); // 3

The reason is to avoid anything that could look like a function declaration.

Also note that for std::vector form 1 may lead to some surprising behaviour, because the initialization list constructor takes precedence. So

std::vector<int> v{1,2}; // two elements: 1 and 2

is not the same as

std::vector<int> v = std::vector<int>(1, 2); // 1 element: 2
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • @bRadGibson You can safely use form `3`. You can also use `1` and `2` for `buf2_`. – juanchopanza Jul 27 '15 at 22:26
  • Thank you for the rationale--that does make sense. Upvoted. I'm marking @Lightness' answer as correct, though as she provided a solution which accesses vector's fill constructor and class' member initialization feature. – U007D Jul 27 '15 at 22:46
2

Any idea what am I missing?

Valid syntax? Not sure where you read this was valid.

Use curlies, or =:

struct Foo
{
  std::vector<char> buf_ = std::vector<char>(10);
  std::vector<std::vector<char>> buf2_{10, std::vector<char>(20)};
};

The relevant grammar production is a brace-or-equal-initializer, which holds a clue in its name. :)

T.C.
  • 133,968
  • 17
  • 288
  • 421
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • I hadn't read this as valid anywhere--I'd been trying to figure it out. Your solution showed me that I was also conflating uniform initializers with initialization lists -- I'd mentally dismissed this as a possible solution as a result. Thank you! – U007D Jul 27 '15 at 23:06
  • @bRadGibson: Ah so the old "programming by guessing" approach? Awesome! Next time it might be worth doing some reading before asking why your guessed code doesn't work.... – Lightness Races in Orbit Jul 27 '15 at 23:07
  • 1
    Lightness, I'd downvote your above comment, if I could. Please check to ensure you have the facts before casting assertions. As mentioned in my question, I had done research. Several hours worth, in fact. I see no need to assume someone is lazy if they don't yet know what you know. – U007D Jul 27 '15 at 23:48
  • @bRadGibson: I made no unfounded assertion. I wondered out loud where you read that you could perform initialisation as you did in the question. You outright stated that you did not read it anywhere. Therefore, you were programming by guessing. No need to take it so personally when I point that out. :) And I did not call you "lazy": I will thank you not to slander me. – Lightness Races in Orbit Jul 28 '15 at 09:32
  • Right, because there are only two possibilities? Sorry, we'll have to agree to disagree. Thank you for your answer, but the unfounded assertions and sarcasm are neither warranted or appreciated. I'll leave it at that. – U007D Jul 28 '15 at 12:54
  • @bRadGibson: I have not utilised any "sarcasm", and I just explained why my "assertion" was entirely founded. _Stop slandering me_. I do not appreciate your misrepresentations. At all. – Lightness Races in Orbit Jul 28 '15 at 13:12
  • @LightnessRacesBY-SA3.0 I found this question in google, after fill constructor for vector not working for me: `vector (size_type n, const value_type& val, const allocator_type& alloc = allocator_type());`. Looks like, similar to the person asking the question, I assumed (yes, I "guessed" too :D) that it should be working within the class, so it was a surprise that it didn't. Any idea why? Is it because `allocator_type` can't be omitted here? Your answer looks to work, but no idea why. Also: http://www.cplusplus.com/reference/vector/vector/vector/ – Kusavil Jan 31 '20 at 17:30
  • What I wanted to do by myself was: `int n=5; vector> goat(n, vector(n, 0))` , which within a class I had to turn into `vector> goat = vector> (n, vector(n, 0));` so it can work – Kusavil Jan 31 '20 at 17:32