Попытка использовать конструктор заполнения вектора при инициализации члена класса не удалась. Что случилось?

При использовании конструктора заполнения std::vector (любой формы) с функцией инициализации члена класса C++11 следующий код не может быть скомпилирован (в 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
}

Я искал проблемы вокруг конструкторов векторной заливки и инициализации членов класса, но они оказались пустыми. Есть идеи, что мне не хватает?

2 ответа

Решение

Есть идеи, что мне не хватает?

Действительный синтаксис? Не уверен, где вы читали это было действительно.

Используйте завитки или =:

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

Соответствующее производство грамматики - инициализатор скобки или равный, который содержит подсказку в его имени.:)

Инициализация на месте нестатических элементов данных не допускается с использованием этого синтаксиса. Вам нужна форма

T t{args}; // 1

или же

T = t{args}; // 2

или же

T = t(args); // 3

Причина в том, чтобы избегать всего, что может выглядеть как объявление функции.

Также обратите внимание, что для std::vector форма 1 может привести к неожиданному поведению, потому что конструктор списка инициализации имеет приоритет. Так

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

это не то же самое, что

std::vector<int> v = std::vector<int>(1, 2); // 1 element: 2
Другие вопросы по тегам