如何获得指向非const std :: string的第一个元素的指针,即使它是空的。
我知道字符串的容量大于1,但是,只需使用
&my_string.front()
触发“超出范围的迭代器”断言失败,因为该字符串为空。使用成员函数
data()
也不适合,因为我想要一个char *类型的指针,而不是const char *。我想我可以在这里执行const_cast,但这似乎并不整齐。
有一个更好的方法吗?
让string::data()
返回char*
你不得不升级到C ++ 17。如果你真的需要对底层数据有写访问权,那么data()
的const_cast'ing结果可能是可行的选择。
虽然front()
将投掷在这里,my_string[my_string.size()]
现在被认为是有效的 - 你不能用它做多少,但you can take and store its address(所以,&my_string[0]
)。
但是,这样做的唯一值得怀疑。所以你可以假设第一组字符插入(直到当前容量)实际上不会使你的指针无效,但你的代码将不清楚正确性,如we are specifically told by string.require¶4 not to rely on it:
引用
basic_string
序列元素的引用,指针和迭代器可能会被该basic_string
对象的以下用法无效:
- 作为任何标准库函数的参数,将非const
basic_string
作为参数引用。- 调用非const成员函数,除了
operator[]
,at
,data
,front
,back
,begin
,rbegin
,end
和rend
。
因此,实际上并不确定指向的特殊“空”缓冲区实际上是否与最终用于存储实际字符串的缓冲区相同(尽管该缓冲区也将以相同方式保证以空值终止)。当然,一旦你超过容量,所有赌注都完全关闭,你真的想跟踪那个事件吗?
这听起来真的像std::string
不是你想要的,或者你应该访问data()
而不是一次调用它然后存储结果指针。
如果你正在与一些需要存储这个指针的C API进行交互,我会切换到其他东西,也许是一个固定长度的字符缓冲区。在C ++方面,您仍然可以使用std::string_view
使用类似C的字符缓冲区来执行令人满意的(只读)事务,因此您不会丢失任何内容。
#include <string_view>
#include <iostream>
void OkayCApiStoreThisThen(const char*) {}
static constexpr const size_t BUF_SIZE = 255;
char silly_buf[BUF_SIZE] = {};
int main()
{
// Sadface
OkayCApiStoreThisThen(silly_buf);
// Happyface
std::string_view str(silly_buf, sizeof(silly_buf));
silly_buf[0] = 'l';
silly_buf[1] = 'o';
silly_buf[2] = 'l';
silly_buf[3] = '!';
std::cout << str.substr(0, 3) << '\n';
}