访问 std::string 中的元素,其中字符串的位置大于其大小
Access elements in std::string where positon of string is greater than its size
在 std::string 的情况下,如果我们访问一个元素,其中(element position) == (size of string)
标准说它返回对值为charT()
的charT
类型的对象的引用。
const_reference operator[](size_type pos) const;
reference operator[](size_type pos);
期望: pos <= size()。
返回: *(begin() + pos) 如果 pos
http://eel.is/c++draft/strings#string.access-1
不幸的是,我无法对此进行推理,如果它是未定义的行为会更好。
有人可以解释这背后的理由吗?
您必须考虑完整的规格。
首先:
期望: pos <= size()。
如果你不遵循前提条件,无论如何你都会有未定义的行为。现在。。。
返回: *(begin() + pos) 如果 pos
"否则"所指的唯一(有效)情况是当pos == size()
.这可能是为了模拟具有可以访问的some_string[size]
元素的 c 字符串行为。请注意,charT()
通常只是' '
。
PS:有人可能会认为要实现该规范,operator[]
必须检查是否pos == size
。但是,如果底层字符数组在字符串末尾有一个charT()
,那么您基本上可以免费获得所描述的行为。因此,看起来与对数组的"通常"访问略有不同,实际上就是这样。
语句 1 是语句 2 的前提条件:
期望:
pos <= size()
.返回:
*(begin() + pos) if pos < size()
.否则(所以这里唯一可行的可能性是
pos == size()
),返回对值为charT()
的charT
类型的对象的引用(即' '
),其中将对象修改为charT()
以外的任何值会导致未定义的行为。
str[str.size()]
基本上指向 null 终止符字符。您可以读取和写入它,但您只能在其中写入' '
。
运算符期望pos
小于或等于size()
,因此如果它不小于,则它应该相等。
除了前面的答案之外,请查看libcxx
(llvm 实现)定义std::string::operator[]
如下:
template <class _CharT, class _Traits, class _Allocator>
inline
typename basic_string<_CharT, _Traits, _Allocator>::const_reference
basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) const _NOEXCEPT
{
_LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
return *(data() + __pos);
}
template <class _CharT, class _Traits, class _Allocator>
inline
typename basic_string<_CharT, _Traits, _Allocator>::reference
basic_string<_CharT, _Traits, _Allocator>::operator[](size_type __pos) _NOEXCEPT
{
_LIBCPP_ASSERT(__pos <= size(), "string index out of bounds");
return *(__get_pointer() + __pos);
}
看看正确抛出的.at()
。
template <class _CharT, class _Traits, class _Allocator>
typename basic_string<_CharT, _Traits, _Allocator>::const_reference
basic_string<_CharT, _Traits, _Allocator>::at(size_type __n) const
{
if (__n >= size())
this->__throw_out_of_range();
return (*this)[__n];
}
如您所愿,在第一种情况下,有一个运行时断言(感谢 t.niese 指出),它仅在调试模式下触发,而第二种将始终抛出,无论库的构建选项如何。
- 将值指定给向量(2D)的向量中的某个位置
- 使用Unreal C++获取VR耳机的世界位置/方向
- 写入位置0x0000000C时发生访问冲突
- 大于65535的C++数组[size]引发不一致的溢出
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 查找最接近的大于当前数字的数字的索引
- GL_SHADERSTORAGE_BUFFER位置是否与其他着色器位置冲突
- 如何使用cudaMallocManaged在指针位置初始化对象?(C++)
- 无法获取webot::PositionSensor对象中位置传感器的值
- 非常量变量只读位置的赋值
- 如何定义更改car类中car位置的方法
- 使用迭代器时如何访问对象在向量中的位置?
- 更改.cpp程序的输入文件中数据的位置会意外更改输出
- 求最大元素位置的分治算法
- 你好。。。id_public变量不应该给出结果为 81 和 86 吗?为什么它为两个派生类占用不同的内存位置?
- 为什么我的点没有在 OpenGL 中绘制鼠标所在的位置?
- 如何将元素添加到向量的字符串位置
- 如何选择在 csv 文件中输出的位置
- 无法打开 fstream C++文件,即使它与 .cpp 位于同一位置
- 访问 std::string 中的元素,其中字符串的位置大于其大小