(C++) Вектор STL векторов STL

Я реализую Matrix с общим вектором общих векторов (vector<vector<T>>).
Мой конструктор получает вектор векторов и инициализирует элемент данных с помощью CCTOR, предоставляемого библиотекой. Когда я пытаюсь инициализировать матрицу с помощью агрегированной инициализации, работает следующая строка кода:
Matrix<int> mat({ {1, 2, 3} });
Но следующий нет:
Matrix<int> mat({ {1, 2, 3}, {4, 5 ,6} });
Ошибки нет. Просто, казалось бы, бесконечный цикл. Мне здесь явно чего-то не хватает. В чем моя ошибка?

Вот мое определение матрицы:

template<class T>
class Matrix {
private:
    int _height;
    int _length;
    vector<vector<T>> _val;
public:
    Matrix(vector<vector<T>> val) throw (const char*) :_height(val.size()), _length((*val.begin()).size()), _val(val) {
        // Checking if the rows are of different sizes.
        vector<vector<T>>::iterator it = val.begin();
        it++;
        while (it != val.end()) {
            if ((*it).size() != _length) {
                throw "EXCEPTION: Cannot Create Matrix from Vectors of Different Sizes.";
            }
        }
    }
}

Также есть функция вывода, но я не думаю, что это имеет к ней какое-то отношение.

Что за сообщение об ошибке? Как выглядит ваш код в Matrix? Этой информации недостаточно, чтобы составить точку зрения.

L. Kue 16.07.2018 01:35

@ L.Kue добавил мой матричный код (CTOR и датамеры). И здесь нет ошибки, просто бесконечный цикл.

Omer Lubin 16.07.2018 01:40

@Marker добавил это.

Omer Lubin 16.07.2018 01:41
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
76
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

В этой части вашего кода

while (it != val.end()) {
        if ((*it).size() != _length) {
            throw "EXCEPTION: Cannot Create Matrix from Vectors of Different Sizes.";
        }
    }

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

Чтобы исправить это, измените свой конструктор на это:

Matrix(vector<vector<T>> val) throw (const char*) :_height(val.size()), _length((*val.begin()).size()), _val(val) {
    // Checking if the rows are of different sizes.
    auto it = val.begin();
    while (it != val.end()) {
        if ((*it).size() != _length) {
            throw "EXCEPTION: Cannot Create Matrix from Vectors of Different Sizes.";
        }
        ++it; // this line is added
    }
}

Таким образом, ваш итератор будет обновляться каждый цикл. Также обратите внимание, что throw (const char*) устарел. Вместо этого рассмотрите возможность использования noexcept(false). И пока вы это делаете, конструкторы с одним аргументом должны быть помечены как explicit, чтобы избежать неявного преобразования типов.

Обновлено: Также стоит посмотреть: Почему «использование пространства имен std» считается плохой практикой?

Ой. Вот и все. Большое спасибо, не могу поверить, что забыл обновить итерацию!

Omer Lubin 16.07.2018 01:56

Другие вопросы по теме