C++ std::字符串's'通过`&;转换为char*;s[0]`-这是如何/为什么工作的?
我遇到过使用std::string来接收缓冲区的例子 这里是简化的:C++ std::字符串's'通过`&;转换为char*;s[0]`-这是如何/为什么工作的?,c++,stdstring,C++,Stdstring,我遇到过使用std::string来接收缓冲区的例子 这里是简化的: error_enum_t get_fn(char*,unsigned long,unsigned long*); void getStringValuedAttribute(标准::字符串和值) { 如果(value.size()==0){ 值。调整大小(32); } 无符号长实际_大小; 获取_-fn(&value[0]、value.size()、实际_-size)); 如果(实际大小>=value.size()){ 值。调
error_enum_t get_fn(char*,unsigned long,unsigned long*);
void getStringValuedAttribute(标准::字符串和值)
{
如果(value.size()==0){
值。调整大小(32);
}
无符号长实际_大小;
获取_-fn(&value[0]、value.size()、实际_-size));
如果(实际大小>=value.size()){
值。调整大小(实际大小+1);
获取\u fn(值[0]、值.size()和实际\u大小);
}
}
在对repl.it进行了一些挖掘之后,我发现&value[0]
是类型char*
,我想这是有道理的,因为value[0]
必须是char
。但这似乎是为了直接访问值
的缓冲区。这就是这里发生的一切,还是有更多的巫术正在进行
我试着挖掘basic_string.h
的源代码,我看到了\u M_local_buf
,但是有大量的模板操作正在进行,这不是我的强项
如果我不得不打赌,value[]
正在利用operator[]
重载来访问指向内部缓冲区开头的指针引用,该指针引用与char*
兼容,因此get\fn
能够将其视为普通缓冲区
我的评估正确吗?这是一个明智的成语吗?不,它安全吗
这是对值的缓冲区的直接访问
正确(C++11)
在实践中正确(C++99)
正如@remy lebeau评论并在a中解释的(也提到):在C++11之前,这是不标准的
您可以看到,对于C++98std::string::data
返回指向数组的指针,该数组包含与构成字符串对象值的字符相同的字符序列
因此,从理论上讲,您可以使用一个C++98实现来返回这个std::string
状态的副本。但实际上,如前所述,实现允许它是真正的字符串数据
而对于C++11std::string::data
返回指向数组的指针,该数组包含表示字符串对象当前值的以null结尾的字符序列(即C字符串)
此数组包含组成字符串对象值的相同字符序列,以及结尾的附加终止空字符('\0')
指针返回指向字符串对象当前用于存储符合其值的字符的内部数组
string::data和string::c_str都是同义词,返回相同的值
现在更一致了
这是一个明智的成语吗?不,它安全吗
它是安全的,从C++11开始,它是100%安全的
我认为,由于它们基本上是一样的,最明智的做法是使用
std::string::data
,因为它更易读,并且保持语义正常。这是一种技巧。取而代之的是,使用“似乎这是在直接访问值的缓冲区”——这正是它所做的。虽然从技术上讲,这直到C++11才正式合法,但这是一种常见的做法,因为大多数实现都允许这样做。“如果我必须打赌,…我的评估正确吗?”-是的。@scohe001它不是一个hack,并且.data()
返回const char*
,您将使用const\u cast
来进行施法,这是一个可怕的hack。直到:“从c++17开始,str.data()返回一个char*,而不是const char*”。此外,根据CPLUS PLUSS.com,“String::DATA和String::CySTR是同义词,返回相同的值。”作为C++11,这对C++ C++ Grand Hordon有很大启发。我处理的大部分内容都与ROS相关,一般来说,强制执行-std=c++11
最小值似乎是理所当然的事情。但很高兴知道,在11点之前,界面会发生微妙的变化。