C++98/03
不可能。字符串可能使用复制时写入,因此需要处理所有读取和写入。
C++11/14
在 [string.require] 中:
basic_string
对象中的类似字符的对象必须被连续存储。也就是说,对于任何 basic_string
对象 s
,当满足 0 <= n < s.size()
的所有值 n
时,标识 &*(s.begin() + n) == &*s.begin() + n
必须成立。
所以 &str.front()
和 &str[0]
应该可以工作。
C++17
str.data()
、&str.front()
和 &str[0]
都可以工作。
这里 有所说明:
charT* data() noexcept;
返回值:指针 p
,满足对于每个 i
在 [0, size()]
范围内,都有 p + i == &operator[](i)
。
复杂度:常数时间。
要求:程序不得更改存储在 p + size()
处的值。
非 const 的 .data()
可以正常工作。
最近的草案 对 .front()
的措辞如下:
const charT& front() const;
charT& front();
要求: !empty()
。
效果:等同于 operator[](0)
。
对于 operator[]
,草案中的措辞如下:
const_reference operator[](size_type pos) const;
reference operator[](size_type pos);
要求: pos <= size()
.
返回值: 如果 pos < size()
,则返回 *(begin() + pos)
。否则,返回一个类型为 charT
的对象的引用,该对象的值为 charT()
,修改该对象会导致未定义行为。
异常:无。
复杂度:常数时间。
因此它使用迭代器算术运算。因此我们需要检查关于迭代器的信息。这里说:
3. basic_string是一个连续的容器([container.requirements.general])。
因此我们需要去 这里:
连续的容器是指支持随机访问迭代器([random.access.iterators])并且其成员类型 iterator
和 const_iterator
是连续迭代器([iterator.requirements.general])的容器。
接着这里:
进一步满足以下要求的迭代器,对于整数值n和可解引用的迭代器值a
和(a + n)
,*(a + n)
等价于*(addressof(*a) + n)
,被称为连续迭代器。
显然,连续迭代器是C++17新增功能,详见这些 论文。
该要求可以重写为:
assert(*(a + n) == *(&*a + n));
在第二部分中,我们取消引用迭代器,然后获取它指向的值的地址,然后对其执行指针算术运算,再次取消引用,这与递增迭代器并取消引用相同。这意味着连续的迭代器指向存储每个值的内存,这些值紧挨着彼此存储,因此是连续的。由于接受
char*
的函数希望得到连续的内存,因此您可以将
&str.front()
或
&str[0]
的结果传递给这些函数。
std::string
中添加了非const的data()
,但它仍然表示您不能修改缓冲区。 嗯?它在哪里说了? - ildjarn&std[0]
&str.font()
之前,请确保有内存,即str.size() > 0
。如果你只是实例化了str
,请使用str.resize()
。 - Garf365.data()
应该可以正常工作。 - user3624760std::string
转换为const char*
或char*
- Gabriel Staples