自Qt 3以来,这个问题已经被讨论了好几次,QtCore的维护者表示在Qt 7之前(如果有的话)不会有任何改变。当时讨论进行时,我就想着总有人会在Stack Overflow上提出这个问题,可能还会在其他几个论坛和问答网站上提出。让我们试着揭开谜团。
总的来说,你需要明白这里没有更好或更差的选择,因为QVector并不是std::vector的替代品。后者不执行写时复制(COW),这也是有代价的。它基本上是为不同的用例而设计的。它主要用于Qt应用程序和框架本身,在早期主要用于QWidgets。
size_t也有它自己的问题,下面我会指出。我不会解释维护者的意思,只会直接引用Thiago的话来传达
官方立场:
因为有两个原因:
1)它被签署是因为我们需要在API的多个地方使用负值:indexOf()返回-1表示未找到值;许多“from”参数可以接受负值以指示从末尾计数。因此,即使我们使用64位整数,我们也需要其带符号版本。这是POSIX ssize_t或Qt qintptr。
这还避免了将无符号转换为有符号时出现的符号更改警告:
-1 + size_t_variable => warning
size_t_variable - 1 => no warning
2) 这是为了避免转换警告或与使用大于int的整数相关的丑陋代码,因此简单地使用“int”。
io/qfilesystemiterator_unix.cpp
size_t maxPathName = ::pathconf(nativePath.constData(), _PC_NAME_MAX);
if (maxPathName == size_t(-1))
io/qfsfileengine.cpp
if (len < 0 || len != qint64(size_t(len))) {
io/qiodevice.cpp
qint64 QIODevice::bytesToWrite() const
{
return qint64(0);
}
return readSoFar ? readSoFar : qint64(-1);
那是 Thiago 发来的一封电子邮件,然后 还有另一个 你可以找到一些详细的答案:
即使在今天,具有4 GB(甚至2 GB)以上核心内存的软件也是例外而不是规则。查看某些进程工具的内存大小时,请注意它们并不代表实际内存使用情况。无论如何,在这里我们谈论的是一个单一容器访问超过2 GB的内存。由于Qt容器的隐式共享和写时复制特性,这可能会非常低效。编写此类代码时需要非常小心,以避免触发COW,从而使内存使用量翻倍或更高。此外,Qt容器不能处理OOM情况,因此如果您接近内存限制,则使用Qt容器是错误的选择。我系统上最大的进程是qtcreator,它也是唯一一个在VSZ(4791 MB)中跨越4 GB标记的进程。您可以认为这表明需要64位容器,但您是错误的:Qt Creator没有任何需要64位大小的容器,它只需要64位指针。它没有使用4 GB的内存。那只是VSZ(映射内存)。目前对Creator可访问的总RAM仅为348.7 MB。而且它使用了超过4 GB的虚拟空间,因为它是一个64位应用程序。因果关系与您预期的相反。为了证明这一点,我检查了填充消耗的虚拟空间:800 MB。32位应用程序永远不会这样做,因为这占用了4 GB可寻址空间的19.5%。(填充是分配但没有被任何东西支持的虚拟空间;它只是存在,以便其他东西不会映射到这些页面上)
进一步了解Thiago的回答,看看这个:
就我个人而言,我非常高兴Qt集合大小是有符号的。对我来说,一个整数值可能在使用减法表达式时无符号(例如size_t),这似乎很疯狂。
整数无符号并不能保证涉及该整数的表达式永远不会为负数,只能保证结果将是绝对灾难。
另一方面,C和C ++标准定义了无符号溢出和下溢的行为。
有符号整数不会溢出或下溢。我的意思是,它们会因为类型和CPU寄存器有限的位数而发生,但标准规定它们不会。这意味着编译器将始终进行优化,假设您不会溢出或下溢它们。
示例:
for (int i = 1
这段代码被优化为无限循环,因为有符号整数不会溢出。如果您将其更改为无符号,则编译器知道它可能会溢出并返回零。一些人不喜欢这样做:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30475
size_t
这样的存在... - The Paramagnetic CroissantQByteArray
,在我的领域中完全可以实现... - user3735658