如何获取指向std :: string的第一个元素的指针,即使它是空的

问题描述 投票:3回答:2

如何获得指向非const std :: string的第一个元素的指针,即使它是空的。

我知道字符串的容量大于1,但是,只需使用

&my_string.front()

触发“超出范围的迭代器”断言失败,因为该字符串为空。使用成员函数

data()

也不适合,因为我想要一个char *类型的指针,而不是const char *。我想我可以在这里执行const_cast,但这似乎并不整齐。

有一个更好的方法吗?

c++ stdstring
2个回答
3
投票

string::data()返回char*你不得不升级到C ++ 17。如果你真的需要对底层数据有写访问权,那么data()的const_cast'ing结果可能是可行的选择。


3
投票

虽然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[]atdatafrontbackbeginrbeginendrend

因此,实际上并不确定指向的特殊“空”缓冲区实际上是否与最终用于存储实际字符串的缓冲区相同(尽管该缓冲区也将以相同方式保证以空值终止)。当然,一旦你超过容量,所有赌注都完全关闭,你真的想跟踪那个事件吗?

这听起来真的像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';
}
© www.soinside.com 2019 - 2024. All rights reserved.