Как инициализировать переменную-член вектора в определении класса?

Следующий код компилируется OK с использованием XCode 5.0, но не Visual Studio 2013.

#include <vector>

class VectorInit
{
private:
    std::vector<int> m_vector{1, 2, 3};   // fails to compile using VS 2013
};

int main()
{
    std::vector<int> vector{1, 2, 3};

    VectorInit vectorInit;

    return 0;
}

Это ошибка, о которой сообщает Visual Studio:

Error   1   error C2664: 'std::vector<int,std::allocator<_Ty>>::vector(std::initializer_list<int>,const std::allocator<_Ty> &)' : cannot convert argument 3 from 'int' to 'const std::allocator<_Ty> &' c:\visual studio 2013\projects\vector-init\main.cpp 6   1   vector-init

Мне не удалось найти пример того, как инициализировать такой вектор в определении класса.

Какой компилятор правильный?

Если синтаксис неверен, является ли единственным вариантом инициализировать m_vector в списке инициализаторов конструктора?


person ksl    schedule 05.02.2014    source источник
comment
Visual 2013 еще не подходит для нестатического члена при инициализации класса во всех случаях, агрегат не работает, например, видя только конструктор копирования. Initializer_list тоже ctor.   -  person galop1n    schedule 05.02.2014
comment
@ galop1n Извините, я не совсем понимаю ваш комментарий. Пожалуйста, можете уточнить.   -  person ksl    schedule 05.02.2014
comment
в инициализации члена класса — это функция С++ 11, дебютировавшая в VS2013. Но когда член является агрегатом, компилятор ошибается и вместо этого пытается использовать конструктор копирования. Он также игнорирует конструкторы, принимающие список инициализаторов, и пытается сопоставить параметры только с обычными конструкторами.   -  person galop1n    schedule 05.02.2014
comment
@ galop1n Спасибо за разъяснения.   -  person ksl    schedule 05.02.2014


Ответы (2)


Инициализация члена класса — это функция С++ 11, дебютировавшая в VS2013. Но когда член является агрегатом, компилятор ошибается и вместо этого пытается использовать конструктор копирования. Он также игнорирует конструкторы, принимающие список инициализаторов, и пытается сопоставить параметры только с обычными аргументами конструкторов.

В качестве обходного пути вы можете создать временный вектор, а затем двигаться с этим синтаксисом до надлежащего обновления компилятора.

class VectorInit
{
private:
    std::vector<int> m_vector { std::vector<int>{ 1, 2, 5, 7 } };
};
person galop1n    schedule 05.02.2014

Как инициализировать переменную-член вектора в определении класса (C++11)

То, что вы делаете, правильно. Он инициализирует член данных, чтобы иметь значения 1, 2, 3 всякий раз, когда вы создаете экземпляр VectorInit.

Однако, если вам нужен другой конструктор, который требует(), вам нужен альтернативный синтаксис:

std::vector<int> m_vector = std::vector(5, 42); // five elements set to 42

Какой компилятор правильный?

Синтаксис действителен для C++, поэтому компиляторы, отличные от VS, правы.

Если ваш компилятор не поддерживает этот тип инициализации, вы можете добавить в свой класс конструктор в качестве обходного пути:

class VectorInit
{
public:
  VectorInt() : m_vector{1, 2, 3}{}
private:
    std::vector<int> m_vector;
};
person juanchopanza    schedule 05.02.2014
comment
Почему не частный (один векторный конструктор принимает initializer_list)? - person ; 05.02.2014
comment
@DieterLücking Это еще один вариант, хотя он решает другую проблему (как и мой второй пример). - person juanchopanza; 05.02.2014
comment
@juanchopanza Компилятор VS 2013 также не примет этот синтаксис. - person ksl; 05.02.2014