为什么 QList::at() 不检查索引是否存在并返回只读值? [英] Why doesn't QList::at() check if index exists and also returns a read-only value?
问题描述
这个问题更多的是询问,而不是实际寻求问题的解决方案.
QList::at()
不仅不检查索引是否越界,而且还返回一个 const
因此它只能用于只读
场景:
const T &QList::at(int i) const
返回列表中索引位置 i 处的项目.我必须是有效的列表中的索引位置(即 0 <= i 此功能非常快(恒定时间). 我刚刚在尝试为列表中的元素分配新值时发现了 在 std::vector::at 该函数自动检查 n 是否在向量中有效元素的范围内,如果不在则抛出 out_of_range 异常 一开始我以为不包括检查是为了确保此功能非常快(恒定时间)".然而,在查看了 检查越界需要做两件事(据我所知): 检查给定的索引是否< 这又是 因此访问它们并计算它们的差异并不会对性能造成太大影响(显然它有一些轻微影响,因为它引入了一些访问和算术运算以及由于 那么为什么要转储索引有效性检查呢?性能影响真的那么大吗? 通过这样做, 在 如果您查看文档,您会发现最后一个很简单: 与 at() 相同.此函数以恒定时间运行. 所以我们只剩下第一个 ( 如果在当前正在共享的列表上调用此函数,它将触发所有元素的副本.否则,此函数以恒定时间运行.如果您不想修改列表,您应该使用 注意:对于 请注意,使用非常量运算符会导致 1 对于 这意味着您不能直接在非常量共享 我的猜测是 关于对索引的检查,这可能是为了保持 This question is more of an inquiry then actually seeking a solution for a problem. const T &QList::at(int i) const Returns the item at index position i in the list. i must be a valid
index position in the list (i.e., 0 <= i < size()). This function is very fast (constant time). I've just found out these peculiar implementation details of In std::vector::at The function automatically checks whether n is within the bounds of valid elements in the vector, throwing an out_of_range exception if it is not At first I thought that the check is not included to ensure the "This function is very fast (constant time)." however after looking at the implementation of A check for out of bounds would require two things (as far as I know): Check if given index is < This is again so accessing those and calculating their difference is not hurting the performance that much (obviously it has some minor impact since it introduces a couple of access and arithmetic operations plus backing up and restoring the stack due to the jump inside the So why dump the check for index validity? Is the performance impact actually that big? By doing so the There are "3" ways of accessing an item from its index in a If you look at the doc, you will see that the last one is simply: Same as at(). This function runs in constant time. So we are left with the first one ( If this function is called on a list that is currently being shared, it will trigger a copy of all elements. Otherwise, this function runs in constant time. If you do not want to modify the list you should use Note: This is also true for Note that using non-const operators can cause 1 For This means that you cannot use My guess is that the purpose of the Regarding the check on the index, this is probably to keep the behavior of the 这篇关于为什么 QList::at() 不检查索引是否存在并返回只读值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!QList
的这些特殊实现细节,我想知道是否有理由这样做.不检查索引有效性
C++ STL
中,如果我们采用 std::array
或 std::vector
(我不采用 std::list
因为它根本没有 std::list::at()
)我们有以下内容:QList
的实现后,我不得不说,即使包含检查,也可以确保恒定时间(和高速).O(1)
,如果我们使用一些古怪的符号).显然我们不能有负索引(我们可以在 Python
中但它有另一个含义;))QList::size()
- 由于 QList::size()
的实现方式是:inline int size() const Q_DECL_NOTHROW { return d->end - d->begin;}
O(1)
(如果我没记错的话)因为这两个值都存储在QList::d
参数中,该参数是指向struct 数据 {QtPrivate::RefCount ref;int 分配,开始,结束;无效 *数组[1];};
内部的跳转而备份和恢复堆栈QList::size()
函数).返回只读值
QList::at()
函数提供了一个隐藏的和 (omho) 不是很有用的功能,这使得使用它和 QList::[]代码> 更令人困惑.此外,与
std::vector
和 std::array
等效的 C++ STL
允许使用此函数分配新值.QList
中,有3"种方法可以从其索引访问项目:const T&QList::at(int) const夯;QList::operator[](int)const T&QList::operator[](int) const
at
) 和非常量 operator[]
.问题来了,第二个的文档告诉你1:QList::at()
.QVector
也是如此:QVector
进行深度复制.QList
,这实际上只适用于 Qt 5,不适用于 Qt 4(至少在文档中),但对于 QVector
来说 Qt 4,因此 .at
方法可能在所有 Qt 容器之间保持一致.>QList
或非常量 QVector
上使用 operator[]
,您需要做类似的事情:QList
.at
的目的是为您提供一种保证恒定访问时间的方法,无论QList
或 QVector
是(operator[]
不保证).对于标准库容器,您不需要这种方法,因为非常量 operator[]
已经保证在恒定时间内运行(它们永远不会复制).operator[]
的行为,因为与 std::vector
不同,您可能想要使用 .at
任何地方你只需要读取数据.QList::at()
not only doesn't check if an index is out of bounds but it also returns a const
hence it can be used only in a read-only
scenario:
QList
while trying to assign a new value to an element in my list and I'm wondering if there is a reason for doing that.No check for index validity
C++ STL
if we take std::array
or std::vector
(I'm not taking std::list
since it doesn't have std::list::at()
at all) we have the following:
QList
I have to say even if the check was included a constant time (and high speed) is most certainly ensured.
O(1)
if we use some wacky notation). Obviously we can't have negative index (we can in Python
but it has another meaning ;))QList::size()
- constant time is also present here since the way QList::size()
is implemented is:inline int size() const Q_DECL_NOTHROW { return d->end - d->begin; }
O(1)
(if I'm not mistaken) since both values are stored inside the QList::d
parameter which is a pointer tostruct Data {
QtPrivate::RefCount ref;
int alloc, begin, end;
void *array[1];
};
QList::size()
function).Returning a read-only value
QList::at()
function offers a hidden and (omho) not very useful feature which makes the difference in using it and QList::[]
even more confusing. Also the C++ STL
equivalent for std::vector
and std::array
allows assignment of new values using this function.QList
:const T& QList::at(int) const
T& QList::operator[](int)
const T& QList::operator[](int) const
at
) and the non-const operator[]
. Here is the problem, the documentation of the second one tells you that1:
QList::at()
.QVector
:
QVector
to do a deep copy.QList
, this is actually only true for Qt 5, not for Qt 4 (at least in the documentation), but for QVector
it was already true for Qt 4, so the .at
method was probably made consistent between all Qt containers.operator[]
directly on a non-const shared QList
or on a non-const QVector
, you would need to do something like:QList<T> &mySharedQList = ...;
const QList<T> &myConstRef = mySharedQList;
myConstRef[0]; // Only ways not to copy the original QList
.at
is to provide you with a method that guarantees a constant access time, whatever the QList
or QVector
is (which operator[]
does not guarantee). You do not need such method for standard library containers because non-const operator[]
are already guaranteed to run in constant time (they are never going to make a copy).operator[]
since, unlike std::vector
, you probably want to use .at
everywhere you only need to read data.