Является ли векторное резервное пространство всегда линейным? [Дубликат]

У меня была такая же проблема после обновления до Windows 10.

Это сработало для меня

  1. Закрыть Visual Studio
  2. Запустить Powershell в качестве администратора
  3. Выполнить Set-ExecutionPolicy Unrestricted
  4. Запустить Visual studio как admin
  5. Очистить проект и добавить пакет nuget

Если это все еще не работает [edit] devenv.exe.config

Visual Studio 2013: C:\Users\<UserName>\AppData\Local\Microsoft\VisualStudio\12.0

Visual Studio 2015: C:\Users\<UserName>\AppData\Local\Microsoft\VisualStudio\14.0

Добавьте следующие

    <dependentAssembly>
        <assemblyIdentity name="System.Management.Automation" publicKeyToken="31bf3856ad364e35" />
        <publisherPolicy apply="no" />
    </dependentAssembly>
    <dependentAssembly>
      <assemblyIdentity name="Microsoft.PowerShell.Commands.Utility" publicKeyToken="31bf3856ad364e35" />
      <publisherPolicy apply="no" />
    </dependentAssembly>
    <dependentAssembly>
      <assemblyIdentity name="Microsoft.PowerShell.ConsoleHost" publicKeyToken="31bf3856ad364e35" />
      <publisherPolicy apply="no" />
    </dependentAssembly>
    <dependentAssembly>
      <assemblyIdentity name="Microsoft.PowerShell.Commands.Management" publicKeyToken="31bf3856ad364e35" />
      <publisherPolicy apply="no" />
    </dependentAssembly>
    <dependentAssembly>
      <assemblyIdentity name="Microsoft.PowerShell.Security" publicKeyToken="31bf3856ad364e35" />
      <publisherPolicy apply="no" />
    </dependentAssembly>
    <dependentAssembly>
      <assemblyIdentity name="Microsoft.PowerShell.Commands.Diagnostics" publicKeyToken="31bf3856ad364e35" />
      <publisherPolicy apply="no" />
    </dependentAssembly>
84
задан Rob Kennedy 24 February 2010 в 23:15
поделиться

7 ответов

Это было пропущено из стандартного C ++ 98, но позже добавлено как часть TR. Предстоящий стандарт C ++ 0x, конечно, будет содержать это как требование.

Из n2798 (черновик C ++ 0x):

23.2.6 Вектор шаблона шаблона [vector]

1 Вектор представляет собой контейнер последовательности, который поддерживает итераторы с произвольным доступом. Кроме того, он поддерживает (амортизируется) постоянное время вставки и стирания операций в конце; вставлять и стирать в середине, принимать линейное время. Управление хранилищем обрабатывается автоматически, хотя можно дать подсказки для повышения эффективности. Элементы вектора сохраняются смежно, что означает, что если v - вектор, где T - некоторый тип, отличный от bool, то он подчиняется идентификатору & amp; v [n] == & amp; v [0] + n для всех 0 & lt; ; = n & lt; v.size ().

87
ответ дан dirkgently 17 August 2018 в 14:16
поделиться
  • 1
    Это также указано в ИСО 14882, 2-е издание: Раздел 23.2.4 [lib.vector]: «Элементы вектора хранятся смежно, что означает, что если v является вектором & lt; T, Allocator & gt; где T - некоторый тип, отличный от bool, тогда он подчиняется идентификатору & amp; v [n] == & amp; v [0] + n для всех 0 & lt; = n & lt; V.SIZE () & Quot. – Mike Caron 11 May 2009 в 18:52
  • 2
    поэтому s, TR, TC, :) На самом деле C ++ 03 также называется C ++ 98-TC1 (техническое исправление) из того, что я читал – Johannes Schaub - litb 11 May 2009 в 19:02
  • 3
    @litb: Правильно. Я все время забываю, что есть. – dirkgently 11 May 2009 в 19:06
  • 4
    Что относительно векторов векторов? Иннер-векторы находятся прямо после внутренних векторов последней группы? – huseyin tugrul buyukisik 4 April 2016 в 20:04
  • 5
    Как bool специальный как T в векторе? В соответствии с «Элементы вектора хранятся смежно, что означает, что если v является вектором, где T является некоторым типом, отличным от bool». – Thomson 15 October 2016 в 00:26

Да, элементы std :: vector гарантируют непрерывность.

2
ответ дан Benoît 17 August 2018 в 14:16
поделиться
  • 1
    Правильно. Думаю, я использую слишком много из них :) – Benoît 11 May 2009 в 19:23

Как указывали другие ответы, содержимое вектора гарантировано будет непрерывным (за исключением странности bool).

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

14
ответ дан Bill Lynch 17 August 2018 в 14:16
поделиться
  • 1
    Элементы все равно будут храниться в смежном блоке памяти, это будет просто в другом месте. Вопрос был конкретно о смежности. – Dima 11 May 2009 в 18:52
  • 2
    Но существующие указатели и итераторы будут признаны недействительными. – Bill Lynch 11 May 2009 в 19:49
  • 3
    Хорошая точка зрения. Вы должны вставить это в свой ответ, чтобы уточнить, что вы имеете в виду. – Dima 13 May 2009 в 23:33
  • 4
    самый полезный ответ мне – GameDeveloper 22 April 2013 в 10:42
  • 5
    Теперь я знаю, почему вчера моя программа была прервана, когда я зациклился на ней в двойном цикле, удалив некоторые элементы :) Спасибо! – user2891462 30 July 2015 в 15:29

cplusplus.com:

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

1
ответ дан Igor Oks 17 August 2018 в 14:16
поделиться

Стандарт фактически гарантирует, что vector является непрерывным в памяти и что &a[0] может быть передан функции C, которая ожидает массив.

Исключением из этого правила является vector<bool>, который использует только один бит на bool, хотя он имеет непрерывную память, он не может использоваться как bool* (это широко считается ложной оптимизацией и ошибкой).

Кстати, почему бы вам не использовать итераторы? Для этого они нужны.

6
ответ дан Motti 17 August 2018 в 14:16
поделиться
  • 1
    & GT; Кстати, почему бы вам не использовать итераторы? Для этого они нужны. Возможно, он прочитал новую статью Александерску по теме: boostcon.com/site-media/var/sphene/sphwiki/attachment/2009/05/… – Nemanja Trifunovic 11 May 2009 в 19:06
  • 2
    Спасибо за ссылку, я запишу ее в свой список чтения (стараюсь не пропустить статьи Александрессу) – Motti 11 May 2009 в 19:22
  • 3
    Mwahaha, все, кажется, говорят об этой презентации в эти дни. Посмотрите, обсуждение по-прежнему горячо: groups.google.com/group/comp.lang.c ++. Moderated / browse_thread / & hellip; – Johannes Schaub - litb 11 May 2009 в 19:25
  • 4
    Если вы внимательно его прочтете, статья Александреску на самом деле не говорит «Не используйте итераторы в C ++», он говорит «Проверьте D». Подход, который он описывает в этой статье, поразительно схож с любыми существующими языками и структурами, которые поглотили функциональное наследие (List, Scheme, Haskell), и я серьезно сомневаюсь, что синтаксис синтаксиса еще один -С является идеальной отправной точкой для лучшего обработки списка. Некоторое время назад я вкратце попытался убедить его превратить свои таланты в улучшение уже устоявшегося языка, такого как C #, но я не боюсь никакого успеха! :) – Daniel Earwicker 18 February 2010 в 09:23

Я нашел этот поток, потому что у меня есть прецедент, в котором преимуществом являются векторы, использующие непрерывную память.

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

void generate(std::vector<float> v)
{
  float f = generate_next_float();
  v.push_back(f);
}

Теперь я могу передать float вектора в виде массива для функций, связанных с буфером OpenGL. Это также устраняет необходимость в sizeof для определения длины массива.

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

3
ответ дан NobodyImportant 17 August 2018 в 14:16
поделиться
  • 1
    эта функция не имеет для меня никакого смысла. вы хотите передать ссылку или указатель на v, а не на v? потому что передача только v приведет к тому, что внутри функции будет сделана копия, которая перестанет существовать после завершения функции. Таким образом, вы нажимаете что-то на вектор только для удаления вектора, когда функция заканчивается. – johnbakers 5 April 2013 в 01:31

Как уже говорили другие, vector внутренне использует непрерывный массив объектов. Указатели в этот массив должны рассматриваться как недействительные, когда любая неконстантная функция-член называется IIRC.

Однако существует исключение !!

vector<bool> имеет специализированную реализацию, разработанную для экономии места, так что каждый bool использует только один бит. Базовый массив не является смежным массивом арифметики bool и массива на vector<bool> не работает, как vector<T>.

(я полагаю, также возможно, что это может быть справедливо для любой специализации вектора , так как мы всегда можем реализовать новую. Однако std::vector<bool> является единственной, ошибочной, стандартной специализацией, на которой простая арифметика указателя не будет работать.)

5
ответ дан Wuggy 17 August 2018 в 14:16
поделиться
  • 1
    Пользователю не разрешается специализироваться std::vector, и все другие векторы необходимы для использования непрерывного хранилища. Поэтому std::vector<bool> (к счастью) является единственным стандартным вектором, который является странным. (Я твердо придерживаюсь мнения, что эта специализация должна быть устаревшей и заменена, например, std::dynamic_bitset с почти одинаковой функциональностью. Это не плохая структура данных, это просто не вектор.) – Arne Vogel 22 September 2017 в 09:57
Другие вопросы по тегам:

Похожие вопросы: