直接写入std :: string的char*buffer

Lyb*_*rta 7 c++ string language-lawyer c++14 c++17

所以我有一个std::string并且有一个函数可以接受char*并写入它.既然std::string::c_str()std::string::data()回来了const char*,我不能用它们.所以我分配了一个临时缓冲区,用它调用一个函数并将其复制到std::string.

现在我计划处理大量信息,复制这个缓冲区会产生明显的影响,我想避免它.

有人建议使用&str.front()&str[0]但是它会调用未定义的行为吗?

Lyb*_*rta 19

C++ 98/03

不可能.字符串可以在写入时进行复制,因此需要处理所有读取和写入.

C++一十四分之一十一

在[string.require]中:

对象中的char状basic_string对象应连续存储.也就是说,任何basic_string 对象s,身份&*(s.begin() + n) == &*s.begin() + n应持的所有值n这样0 <= n < s.size().

所以&str.front(),&str[0]应该工作.

C++ 17

str.data(),&str.front()&str[0]工作.

这里说:

charT* data() noexcept;

返回:一个指针p,p + i == &operator[](i)用于每个iin [0, size()].

复杂性:恒定时间.

要求:程序不得更改存储的值at 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().

返回:*(begin() + pos) if pos < size().否则,返回对charT具有value 的类型对象的引用charT(),其中修改对象会导致未定义的行为.

投掷:没什么.

复杂性:恒定时间.

所以它使用迭代器算法.所以我们需要检查有关迭代器的信息.这里说:

3 basic_string是一个连续的容器([container.requirements.general]).

所以我们需要去这里:

连续容器是一个容器,它支持随机访问迭代器([random.access.iterators]),其成员类型iteratorconst_iterator连续迭代器([iterator.requirements.general]).

然后在这里:

迭代器进一步满足要求,即,对于n的整数值,并提领迭代值a(a + n),*(a + n)相当于*(addressof(*a) + n)被称为连续的迭代器.

显然,连续迭代器是C++ 17的特性,在这些 文章中添加了它.

该要求可以改写为:

assert(*(a + n) == *(&*a + n));
Run Code Online (Sandbox Code Playgroud)

因此,在第二部分中,我们取消引用迭代器,然后获取它指向的值的地址,然后对其执行指针算法,取消引用它,它与递增迭代器然后解除引用它相同.这意味着连续的迭代器指向内存,其中每个值都紧接着存储,因此是连续的.由于是将函数char*预计连续的内存,你可以传递的结果,&str.front()&str[0]将这些功能.

  • 假设“ operator []”的定义说“修改对象会导致未定义的行为”。我认为您的回答是错误的。我认为这是标准中的缺陷。 (2认同)