我遇到了 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
,因为它更易读 并保持语义正常。