std :: move on std :: string garantee:.c_str()返回相同的结果吗?

Duc*_*een 4 c++ move move-semantics c++11

我想提供零拷贝,基于移动的API.我想将一个字符串从线程A移动到线程B.在意识形态上,似乎移动应该能够简单地将数据从实例A传递到新实例B中,具有最小到无复制操作(主要用于地址).因此,所有数据如数据指针都将被简单地复制而不是新实例(通过移动构造).那么std :: move on std :: string garantee是什么.c_str()在移动之前在实例上返回相同的结果,并通过移动构造函数创建实例?

Ker*_* SB 10

不可以std::string.如果有分配,则不需要使用动态分配或执行任何特定的分配.实际上,现代实现通常将短字符串放入字符串对象本身并且不分配任何东西; 然后移动与复制相同.

重要的是要记住,重要的std::string不是一个容器,即使它看起来非常相似的.容器相对于它们的元素提供了更强的保证std::string.


Jer*_*fin 7

不,这不能保证.

保证它基本上禁止(例如)短字符串优化,其中短字符串的整个主体存储在字符串对象本身中,而不是在堆上单独分配.

至少就目前而言,我认为SSO被认为是非常重要的,委员会将非常不愿意禁止它(但这可能会改变 - 当最初的C++ 98标准被编写时,他们遇到了相当大的麻烦,允许复制 - 写入字符串,但现在禁止它们.


Joh*_*erg 3

不,

但如果需要的话,一个选项是将字符串放入std::unique_ptr. 就我个人而言,我通常不会依赖 c_str() 值超出本地范围。

例如,根据要求:

#include <iostream>
#include <string>
#include <memory>

int main() {
    std::string ss("hello");
    auto u_str = std::make_unique<std::string>(ss);
    std::cout << u_str->c_str() <<std::endl;
    std::cout << *u_str <<std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果你没有 make_unique (C++14 中的新增功能)。

auto u_str = std::unique_ptr<std::string>(new std::string(ss));
Run Code Online (Sandbox Code Playgroud)

或者直接复制STL 提案中的整个实现:

关于如何做到这一点的 Ideone 示例