Ответ 1
Это обсуждалось несколько раз, так как Qt 3 по крайней мере, и сторонник QtCore выразил, что некоторое время назад никаких изменений не произойдет до Qt 7, если он когда-либо будет.
Когда дискуссия продолжалась тогда, я подумал, что рано или поздно кто-то израсходует ее на Stack Overflow... и, вероятно, на нескольких других форумах и Q/A тоже. Попробуем демистифицировать ситуацию.
В общем, вам нужно понять, что здесь нет ничего лучше или хуже, поскольку QVector
не является заменой std::vector
. Последний не делает Copy-On-Write (COW) и поставляется с ценой. Он предназначен для другого варианта использования, в основном. Он в основном используется внутри приложений Qt и самой структуры, первоначально для QWidgets в ранние времена.
size_t
имеет свою собственную проблему, после всего, что я укажу ниже.
Без того, чтобы я интерпретировал для вас сопровождающего, я просто приведу Тьяго непосредственно, чтобы нести сообщение официальная позиция:
По двум причинам:
1) он подписан, потому что нам нужны отрицательные значения в нескольких местах API: indexOf() возвращает -1, чтобы указать значение, не найденное; многие из "от" параметры могут принимать отрицательные значения для указания подсчета с конца. Так что даже если бы мы использовали 64-битные целые числа, нам понадобилась бы подписанная версия. Что POSIX ssize_t или Qt qintptr.
Это также позволяет избежать предупреждений об изменении знака, когда вы неявно конвертируете недостоверности в подписали:
-1 + size_t_variable => warning
size_t_variable - 1 => no warning
2) это просто "int", чтобы избежать предупреждений о конверсиях или уродливого кода, связанного с использование целых чисел больше, чем int.
ю /qfilesystemiterator _unix.cpp
size_t maxPathName = ::pathconf(nativePath.constData(), _PC_NAME_MAX);
if (maxPathName == size_t(-1))
ю /qfsfileengine.cpp
if (len < 0 || len != qint64(size_t(len))) {
ю /qiodevice.cpp
qint64 QIODevice::bytesToWrite() const
{
return qint64(0);
}
return readSoFar ? readSoFar : qint64(-1);
Это было одно электронное письмо от Thiago, а затем есть еще один, где вы можете найти подробный ответ:
Даже сегодня программное обеспечение с памятью ядра более 4 ГБ (или даже 2 ГБ) является исключением, а не правилом. Будьте внимательны при просмотре размеры памяти некоторых инструментов процесса, поскольку они не представляют собой фактическую память использование.
В любом случае мы говорим здесь о том, что одна адресация контейнера более 2 ГБ памяти. Из-за неявного совместного использования и копирования на запись характер контейнеров Qt, которые, вероятно, будут крайне неэффективными. Тебе нужно быть очень осторожным при написании такого кода, чтобы избежать запуска COW и, следовательно, удвоение или ухудшение использования памяти. Кроме того, контейнеры Qt не обрабатывают OOM ситуации, поэтому, если вы находитесь где-то рядом с пределом памяти, контейнеры Qt являются неправильным инструментом для использования.
Самый большой процесс, который у меня есть в моей системе, - qtcreator, и он также является единственным один, который пересекает отметку 4 ГБ в VSZ (4791 МБ). Вы можете утверждать, что это что 64-битные контейнеры необходимы, но вы ошибаетесь:
У Qt Creator нет контейнера, требующего 64-битных размеров, это просто нужны 64-битные указатели
Он не использует 4 ГБ памяти. Это просто VSZ (сопоставленная память). Общая ОЗУ, доступное в настоящее время для Творца, составляет всего 348,7 МБ.
И он использует более 4 ГБ виртуального пространства, потому что он является 64-битным выражение. Связь причинно-следственных связей противоположна тому, что вы ожидать. В качестве доказательства этого я проверил, сколько виртуального пространства потребляется прокладка: 800 МБ. 32-битное приложение никогда не сделает этого, что 19,5% адресное пространство на 4 ГБ.
(заполнение - это виртуальное пространство, выделенное, но не подкрепленное чем-либо, оно только там, чтобы что-то еще не отображалось на эти страницы)
Переходя к этой теме еще дальше с ответами Тьяго, см. это:
Лично я ОЧЕНЬ счастлив, что размеры коллекции Qt подписаны. Кажется орехи мне, что целочисленное значение, потенциально используемое в выражении, используя вычитание будет неподписанным (например, size_t).
Целое число без знака не гарантирует, что выражение, включающее что целое число никогда не будет отрицательным. Это только гарантирует, что результат будет абсолютной катастрофой.
С другой стороны, стандарты C и С++ определяют поведение неподписанных переполнения и недогрузки.
Подписанные целые числа не переполняются и не переполняются. Я имею в виду, они делают, потому что типы и регистры процессора имеют ограниченное количество бит, но стандарты говорят, что они нет. Это означает, что компилятор всегда будет оптимизировать, полагая, или подтолкнуть их.
Пример:
for (int i = 1; i >= 1; ++i)
Это оптимизировано для бесконечного цикла, потому что целые числа со знаком не переполняются. Если вы измените его на unsigned, то компилятор знает, что он может переполняться и вернуться к нулю.
Некоторым людям это не понравилось: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30475