为什么std::vector::data和std::string::data不同?
Why are std::vector::data and std::string::data different?
Vector的新方法data()
提供了const和非const版本。
但是string的data()
方法只提供const版本。
我认为他们改变了关于std::string
的措辞,所以现在要求字符是连续的(像std::vector
)。
std::string::data
刚好错过了吗?还是只允许const访问字符串的底层字符的好理由?
注意:std::vector::data
还有一个很好的特性,在空向量上调用data()
并不是未定义的行为。而&vec.front()
如果为空则为未定义行为
在c++ 98/03中,有很好的理由不使用非const data()
,因为字符串通常被实现为COW。如果refcount大于1,则非const data()
需要进行复制。虽然这是可能的,但在c++ 98/03中并不被认为是理想的。
2005年10月,委员会在LWG 464中投票决定将const和非const data()
添加到vector
,将const和非const at()
添加到map
。当时,string
还没有被修改为禁止COW。但是后来,在c++ 11中,COW string
不再符合。string
规范在c++ 11中也得到了加强,要求它是连续的,并且operator[](size())
总是暴露一个终止null。在c++ 03中,终止null仅由operator[]
的const重载保证。
所以简而言之,一个非const的data()
看起来比一个c++ 11的string
更合理。据我所知,这从来没有被提出过。
charT* data() noexcept;
在2016年2月的Jacksonville会议上由David Sankel的P0272R1将basic_string
添加到c++ 1z工作草案N4582中。
干得好,David!
历史上,字符串数据不是const的,因为它会阻止一些常见的优化,比如写时复制(COW)。现在,ianm已经不那么常见了,因为它在多线程程序中表现得很糟糕。
BTW,是的,它们现在被要求是连续的:
[string.require]。5: basic_string对象中的类char对象应该连续存储。也就是说,对于任何basic_string对象s的恒等式&*(s.p begin() + n) == &* s.p begin() + n对所有n的值都成立,使得0 <= n
std::string ret; strcpy(ret.data(), "whatthe...");
虽然我不是那么精通标准,但这可能是由于std::string
不需要包含以空结束的数据,但它可以并且不需要包含显式的长度字段,但它可以。因此,更改底层数据,例如在中间添加' '
可能会使字符串长度字段与实际的char数据不同步,从而使对象处于无效状态。
@Christian Rau
从最初的Plauger(大约1995年我想)string
类被委员会stl化(变成一个序列,模板化),std::string
一直是std::vector
加上字符串相关的东西(从/到0终止的转换,串联,…),再加上一些奇怪的东西,比如COW,实际上是"Copy on Write和non- const
begin()
/end()
/operator[]
"。
但最终std::string
实际上是另一个名称下的std::vector
,其重点和意图略有不同。所以:
- 就像
std::vector
一样,std::string
要么有size数据成员,要么有开始和结束数据成员; - 就像
std::vector
一样,std::string
不关心其元素的值,嵌入的NUL或其他。
std::string
是而不是,是一个有语法糖、实用函数和一些封装的C字符串,就像std::vector<T>
不是有语法糖、实用函数和一些封装的T[]
一样。
- 使用 .data() 将字符数组转换为 std::string 不会转换整个数组
- 我可以在初始化之前使用 std::array 成员变量中的 data() 指针吗?发出警告
- 如何将 std::string 赋回作为 <char>void* 指针传递的 std::vector.data()?
- 将嵌套的 std::arrays 视为具有链式 .data() 的单个平面数组
- std::vector<std::wstring> 移动/重新分配内部 wstring.data() 合法吗?
- 使用 std::vector,为什么 &vec[0] 未定义的行为,而 vec.data() 是安全的?
- 如何在 OpenMP 4 中为 std::vector 编写"target data map"?
- C++ std::vector.data not found by MinGW
- 通过 std::vector.data() 指向 std::vector 元素的指针指向损坏的数据
- c++将存储在std::vector中的数据传递给c_func(void*data)
- 使用 move std::string 的 .data() 成员不适用于小字符串?
- std::vector: vec.data() or &vec[0]
- Python 的 Visual C++ 无法处理 c++11 错误 C2039:"data":不是 std::vector 的成员
- 如果vector为空,std::vector::data()应该返回什么?
- 当你在 std::vector 上调用 data() 时会发生什么<bool>?
- 为什么std::vector::data和std::string::data不同?
- 是否必须释放std::string.c_str()或std::string.data()返回的指针
- 在保留之后使用std::vector::data
- 关联容器中的 std::array data() 失效的风险
- std::vector::data()是否通过移动而保留