Инициализировать 2D вектор внутри конструктора класса - PullRequest
2 голосов
/ 11 июня 2019

Я хочу инициализировать двумерный массив в конструкторе класса, но компилятор выдает мне эту ошибку "вызов объекта типа класса без соответствующего оператора () или функций преобразования в указатель на тип функции".

class Matrix
{

public:
    Matrix() {};
    Matrix(size_t x, size_t y) { a(x, vector<int>(y , 0 )); }
private:
    vector<vector<int>> a; 


};

Ответы [ 3 ]

6 голосов
/ 11 июня 2019

Во-первых, как уже упоминалось, это:

Matrix(size_t x, size_t y)
{
   a(x, vector<int>(y , 0 ));
}

- это не то, как вы инициализируете участника.Чтобы инициализировать элемент, мы используем список инициализатора элемента , например:

Matrix(size_t x, size_t y)
   : a(x, vector<int>(y , 0 ))
{}

Синтаксис двоеточия - это специальное место для перечисления инициализаций.Ничто в теле конструктора не является инициализацией.Когда вы не ставите инициализатор для члена, он инициализируется по умолчанию.Затем выполняется код в теле вашего конструктора.Как мы знаем, тело функции состоит из операторов , которые выполняются.

Теперь, когда вы выполняете оператор <name>(<thing>, <other thing>), это вызов функции.Если <name> не функция, а экземпляр класса, то вместо этого ищется оператор вызова функции operator().Если его нет (или он не соответствует аргументам), то компиляция завершится не так, как вы наблюдали.

Возможно, язык был спроектирован так, что любое упоминание члена внутритело конструктора, в таком виде, рассматривалось как инициализация?Наверное.Но почему?Теперь у вас не было бы однозначного способа выполнять вызовы функций, и порядок, в котором все происходит во время конструирования, был бы неясен.Теперь все намного лучше.

2 голосов
/ 11 июня 2019

Когда управление передается в тело конструктора, вектор уже создан.

Таким образом, этот оператор

a(x, vector<int>(y , 0 ));

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

Вы можете использовать список mem-initializer в конструкторе

class Matrix
{
public:
    Matrix() {};
    Matrix(size_t x, size_t y) : a(x, vector<int>(y ) ) {}
private:
    vector<vector<int>> a; 
};

Или вы можете использовать функцию-член assign в теле конструктора

class Matrix
{

public:
    Matrix() {};
    Matrix(size_t x, size_t y) { a.assign (x, vector<int>(y ) ); }
private:
    vector<vector<int>> a; 
};
2 голосов
/ 11 июня 2019

Правильный синтаксис использует список инициализатора:

Matrix(size_t x, size_t y) :a(x, vector<int>(y , 0 )) { }

...