c++ - std::string `s` 通过 `&s[0]` 转换为 char* - 这是如何/为什么起作用的?

标签 c++ stdstring

<分区>

我遇到了 this way使用 std::string 接收缓冲区。

这里简化了:

error_enum_t  get_fn(char*, unsigned long, unsigned long*);

void getStringValuedAttribute(std::string &value)
{
  if (value.size() == 0) {
    value.resize(32);
  }

  unsigned long actual_size;
  get_fn(&value[0], value.size(), &actual_size));

  if (actual_size >= value.size()) {
    value.resize(actual_size + 1);
    get_fn(&value[0], value.size(), &actual_size);
  }
}

在对 repl.it 进行一些挖掘之后,我看到 &value[0]char * 类型,我想这是有道理的,因为 value[0 ] 必须是 char。但这似乎可以直接访问 value 的缓冲区。这就是这里发生的一切,还是有更多的魔法在进行?

我试着深入了解 basic_string.h 的源代码,我看到了 _M_local_buf,但是有大量的模板操作正在进行,这不是我的强项。

如果我不得不猜测,value[] 正在利用 operator [] 重载来访问指向内部缓冲区开始的指针引用,这与 char * 兼容,因此 get_fn 能够将其视为普通缓冲区。

我的评估是否正确?这是一个明智的成语,不,它甚至安全吗?

最佳答案

this is giving direct access to value's buffer

正确(C++11)。

在实践中正确 (C++99)。

@remy-lebeau 评论并在(也提到)very similar question 中解释: 在 C++11 之前,这不是标准化的。

可以在this reference中看到对于 C++98 std::string::data

Returns a pointer to an array that contains the same sequence of characters as the characters that make up the value of the string object.

因此,理论上您可以使用 C++98 实现返回此 std::string 状态的拷贝。但实际上,如前所述,实现允许它成为真正的字符串数据。

对于 C++11 std::string::data,不同之处在于:

Returns a pointer to an array that contains a null-terminated sequence of characters (i.e., a C-string) representing the current value of the string object.

This array includes the same sequence of characters that make up the value of the string object plus an additional terminating null-character ('\0') at the end.

The pointer returned points to the internal array currently used by the string object to store the characters that conform its value.

Both string::data and string::c_str are synonyms and return the same value.

现在更加一致。

Is this a wise idiom, nay, is it even safe?

它是安全的,从 C++11 开始它是 100% 安全的。

我认为,因为它们基本相同,所以最明智的做法是使用 std::string::data,因为它更易读 并保持语义正常。

关于c++ - std::string `s` 通过 `&s[0]` 转换为 char* - 这是如何/为什么起作用的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57733300/

相关文章:

c++ - 评估为函数的类模板

c++ - QGraphicsView使用鼠标滚轮在鼠标位置下放大和缩小

c++ - 为什么 `std::string::find()` 在失败时不返回结束迭代器?

c++ - 可以利用 std::basic_string 来实现具有长度限制的字符串吗?

c++ - 从 "const std::string"初始化 "std::istringstream"

c++ - 除非通过引用传递,否则字符串类型无法正常工作

c++ - 从 C++ 启动 matlab 脚本并等待结果

C++ 使用指向非 const 的指针编写 const vector

c++ - 将成员指针作为比较器/"key"的 std 算法

c++11 - 有没有办法在不修改缓冲区内容的情况下设置 std::string 的长度?