Хобрук: Ваш путь к мастерству в программировании

Есть ли обходной путь поддержки VLA (массивы переменной длины) для VS2017?

Такой простой код, как:

int n;
cin >> n;
int s[n], p[2*(n-1)][3];

Я должен перевести на:

int  n;
cin >> n;
vector<int> s(n, 0);
vector<vector<int>> p(2 * (n - 1), vector<int>(3));

Я хотел бы увидеть что-то вроде:

int  n;
cin >> n;
mat s(n), p(2*(n-1), 3);

Я определенно не хочу использовать смесь new\make_unique и std::array+std::vector для таких простых вещей. Две строки - это уродливый беспорядок, ИМХО, поэтому я ищу способ сохранить C как синтаксис.

Итак, что такое обходной путь? Любой определяющий/стандартный заголовок/копируемо-вставляемый тип STL на основе С++?


  • VLA не поддерживаются стандартом C++ (но поддерживаются расширениями некоторых компиляторов, например: g++). 26.01.2018
  • Ответ: В C++ нет VLA. 26.01.2018
  • в чем проблема со вторым фрагментом? Мне совершенно непонятно, в чем вопрос 26.01.2018
  • См. stackoverflow.com /вопросы/5246900/ 26.01.2018
  • Лично я бы сделал p вектором массивов, например std::vector<std::array<int, 3>> p(2 * (n - 1));. 26.01.2018
  • Что касается вашего обновленного заголовка: Есть ли обходной путь поддержки VLA (массивов переменной длины) для VS2017? Если VLA не поддерживаются стандартом C++, почему какой-либо один компилятор должен его поддерживать? Если некоторые предоставляют расширения для такой функциональности, не имеет значения, что они (или любой другой компилятор) должны это делать. 26.01.2018
  • Выделение огромных массивов в стеке — не лучшая идея. 26.01.2018
  • ИМО единственный обходной путь - это второй фрагмент кода в вашем вопросе. Что с этим не так? Если вы думаете, что это ужасный беспорядок, возможно, C++ не для вас. 26.01.2018
  • @Michael Walz: Допустим, вы хотите научить ребенка C++. Ребенок может читать простой код, дети, как правило, немного больше путаются с такими конструкциями, как vector<vector<int>> p(2 * (n - 1), vector<int>(3)); вместо int p[2*(n-1)][3];, потому что шаблонный шаблон длинного кода затеняет/скрывает реальную логику. Еще большая проблема возникает, когда они могут использовать ideone дома и VS2017 для школьных проектов. 26.01.2018
  • Используйте матричный класс, подобный в Dr. Dobb's, или напишите свой собственный . 26.01.2018
  • Хорошо, вопрос на самом деле полностью изменился со всеми вашими правками, может быть, вам следует опубликовать совершенно новый вопрос о том, как написать vector<vector<int>> p(2 * (n - 1), vector<int>(3)); как mat p(2*(n-1), 3); 26.01.2018
  • @Michael: 1) не разъясняет, для чего нужны правки?) 2) для меня это не изменилось, поскольку включение длинного внешнего матричного класса является менее предпочтительным вариантом для добавления некоторых определений для поддержки C / stl include. В VS2017 есть некоторая поддержка C, так что почему им так сложно добавить эту довольно старую функцию, для меня загадка. 26.01.2018
  • @DuckQueen да, конечно, но иногда слишком много правок полностью меняют вопрос, и вы можете получить больше информации, если зададите новый вопрос только о фактической проблеме. Кстати, это не мой отрицательный голос. 26.01.2018
  • В общем, не рекомендуется сохранять синтаксис C в C++. Вместо этого используйте синтаксис C++. 26.01.2018
  • @Xam: только когда синтаксис С++ в чем-то превосходит, здесь это просто отстой =) 27.01.2018

Ответы:


1

Массивы переменной длины не поддерживаются стандартным C++.

std::vector<int> — это идиоматический способ реализации непрерывного блока данных int, размер которого неизвестен во время компиляции. Хорошее эмпирическое правило — использовать std::vector до тех пор, пока вы не найдете вескую причину не делать этого.

26.01.2018

2

Массивы переменной длины (т. е. массивы, в которых хотя бы одно измерение не является постоянной времени компиляции) не поддерживаются в стандартном C++. Следовательно, вы не можете написать что-то вроде cin >> n; int s[n]. Некоторые расширения существуют, но все же - для очень больших значений n могут возникнуть проблемы, если имеющийся компилятор поместит такой массив в "стек", который обычно более ограничен, чем куча.

Стандартным способом является использование std::vector<int> s(n) или, если — хотя обычно это не рекомендуется — по какой-то причине вам нужен «простой» массив, не обернутый объектом, вы можете написать int *s = new int[n];, хотя в этом случае вам придется вызывать delete[] s;, когда вы больше не нужен массив.

26.01.2018
  • Надеюсь, вы не возражаете против моего агрессивного редактирования. Сделайте откат, если вам это не нравится. +1 кстати. 26.01.2018

  • 3

    alloca - еще одна альтернатива. Не стандартно, но широко поддерживается.

    26.01.2018

    4

    В стандарте C++ нет массивов переменной длины (VLA). Либо используйте STL, например std::vector, либо определите переменные как const (которые вы не можете изменить во время выполнения).

    26.01.2018
    Новые материалы

    Аргументы прогрессивного улучшения почти всегда упускают суть
    В наши дни в кругах веб-разработчиков много болтают о Progressive Enhancement — PE, но на самом деле почти все аргументы с обеих сторон упускают самую фундаментальную причину, по которой PE..

    Введение в Джанго Фреймворк
    Схема «работать умно, а не усердно» В этой и последующих статьях я познакомлю вас с тем, что такое фреймворк Django и как создать свое первое приложение с помощью простых и понятных шагов, а..

    Настольный ПК как «одно кольцо, чтобы править всеми» домашних компьютеров
    Вид после 9 месяцев использования С настольных компьютеров все началось, но в какой-то момент они стали «серверами», и мы все перешли на ноутбуки. В прошлом году я столкнулся с идеей настольных..

    Расширенные методы безопасности для VueJS: реализация аутентификации без пароля
    Руководство, которое поможет вам создавать безопасные приложения в долгосрочной перспективе Безопасность приложений часто упускается из виду в процессе разработки, потому что основная..

    стройный-i18следующий
    Представляем стройную оболочку для i18next. Эта библиотека, основанная на i18next, заключает экземпляр i18next в хранилище svelte и отслеживает события i18next, такие как languageChanged,..

    Обзор 20 основных и современных методов работы с массивами в JavaScript
    Вы знаете их всех? В этом коротком посте я покажу сводку методов, доступных в JavaScript для работы с массивами. Я надеюсь, что вы найдете это полезным! В конце поста вы найдете ссылку на..

    Да, но я чувствую необходимость указать, что это или не единственные два.
    Да, но я чувствую необходимость указать, что это или не единственные два. Обучение с подкреплением (в качестве примера) также является важным.