U007D
U007D

Reputation: 6328

Attempting to use vector's fill constructor in class member initialization fails. What is wrong?

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?

Upvotes: 3

Views: 3646

Answers (2)

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385295

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. :)

Upvotes: 2

juanchopanza
juanchopanza

Reputation: 227478

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

Upvotes: 7

Related Questions