std::copy
和
std::uninitialized_copy
表示 std::string
的范围。常规copy
将假设那里已经存在一个字符串。 如果可能的话,字符串的复制赋值运算符将尝试使用字符串中的任何现有空间进行复制。
但是,如果那里还没有字符串,就像未初始化内存的情况一样,复制赋值运算符将访问垃圾内存,并且行为未定义。另一方面,未初始化的副本将
创建那里的字符串而不是分配给它,因此它可以在尚未包含字符串的内存中使用。 本质上,常规版本中会有一个
*it = value;
,未初始化版本中会有类似
new (&(*it)) T(value);
的内容。struct foo { /* whatever */ };
foo f;
alignas(foo) unsigned char buf[sizeof(foo)];
foo *foo_ptr = reinterpret_cast<foo*>(buf);
*foo_ptr = f; // undefined behavior; *foo_ptr does not point at a valid object
new (foo_ptr) foo; // okay; initializes raw memory
*foo_ptr = f; // okay; assignment to an existing object
。 分配内存后,必须通过运行类的构造函数来初始化它。当对象完成时,必须运行类的析构函数。
标准
算法假设它们总是访问初始化的内存,因此可以基于该假设创建、复制、交换、移动和删除等对象。 然而,当处理“未初始化的内存”时,算法必须确保它们不会在从未使用构造函数初始化的内存上运行析构函数。他们必须通过在需要时首先初始化内存等来避免移动和交换不存在的对象......
他们必须处理对象生命周期(初始化)中的额外步骤,这对于已初始化的内存来说是不必要的。