С++ 11 std:: array vs static array vs std::vector
Первый вопрос: хорошо ли начать использовать С++ 11, если я разработаю код для следующих трех лет?
Тогда, если это так, каков наилучший способ реализовать матрицу, если я хочу использовать ее с Lapack? Я имею в виду, что выполнение std::vector<std::vector< Type > > Matrix
нелегко совместимо с Lapack.
До сих пор я сохранил свою матрицу с помощью Type* Matrix(new Type[N])
(форма указателя с new
и delete
была важна, потому что размер массива не задан как число, например 5, а как переменная).
Но с С++ 11 можно использовать std:: array. Согласно этому сайту, этот контейнер кажется лучшим решением... Как вы думаете?
Ответы
Ответ 1
Прежде всего, если вы собираетесь изучать С++, изучите С++ 11. Предыдущий стандарт С++ был выпущен в 2003 году, а это значит, что ему уже десять лет. Это много в мире ИТ. Навыки С++ 11 также плавно переходят к следующему стандарту С++ 1y (скорее всего, С++ 14).
Основное различие между std::vector
и std::array
- это динамическое (по размеру и распределению) и статическое хранилище. Поэтому, если вы хотите иметь матричный класс, который всегда, скажем, 4x4, std::array<float, 4*4>
будет отлично.
Оба этих класса предоставляют член .data()
, который должен создавать совместимый указатель. Обратите внимание, однако, что std::vector<std::vector<float>>
НЕ будет обрабатывать непрерывную память 16*sizeof(float)
(поэтому v[0].data()
не будет работать). Если вам нужна матрица с динамическим размером, используйте одиночный vector
и измените его размер до размера width*height
.
Поскольку доступ к элементам будет немного сложнее (v[width * y +x]
или v[height * x + y]
), вам может понадобиться предоставить класс-оболочку, который позволит вам получить доступ к произвольному полю по строке/столбцу.
Так как вы также упомянули массивы C-стиля; std::array
обеспечивает более удобный интерфейс для работы с одним и тем же типом хранилища и, следовательно, должен быть предпочтительным; нет ничего, чтобы получить со статическими массивами над std::array
.
Ответ 2
Это очень поздний ответ на вопрос, но если кто-то читает это, я просто хочу указать, что почти никогда не следует применять матрицу как "вектор векторов". Причина в том, что каждая строка матрицы сохраняется в некоторой случайной папке в куче. Это означает, что операции с матрицами будут делать много случайных обращений к памяти, что приведет к промахам в кэше, что значительно замедлит реализацию.
Другими словами, если вы вообще не заботитесь о производительности, просто выделите array/std::array/std::vector
размера rows * columns
, затем используйте функции-оболочки, которые преобразуют пару целых чисел в соответствующий элемент массива. Если вам не нужно поддерживать такие вещи, как возврат ссылок на строки матрицы, все эти параметры должны работать нормально.