这是一个例子:
for (std::string key, value; true;)
{
if (!std::getline(stream,key,':')) break;
if (!std::getline(stream,value)) break;
/* implementation */
map.emplace(std::move(key),std::move(value));
key.clear(); // ?
value.clear(); // ?
}
有意见认为,该标准不保证容器移动后内部状态的有效性。在网上找不到任何答案。我想澄清这个问题。谢谢你。
移动后,容器保持正确状态,但未指定它处于哪个状态(有效但未指定)。在他的回答中,@Harry提供了语言标准( lib.types.movedfrom)的相关引用。
这是一种什么样的状态,“正确,但未指定”,标准也有解释。defns.valid:
因此,在您的情况下,对象
key和value类型std::string在移动后处于正确状态。您甚至可以调用该方法
empty()来检查字符串是否为空,它保证返回false, 或true,但没有指定具体的内容。为避免在重用重定位容器时出现任何意外,您必须明确将其置于某个特定状态。例如,用 为空
clear()。此外,移动的字符串可以安全地传递给填充std::getline(),因为 此函数在写入任何内容之前清除字符串。哦找到了!
[lib.types.movedfrom]. 由我突出显示。因此,如果移动后容器中仍有东西,那么这就像它是空的一样是允许和正常的。
事实上,他们只承诺不会有像空容器那样的麻烦,它
size()会返回一个非零数字或类似的东西。PS好吧,你不需要清理任何东西来阅读 - 同样,如果你正确阅读,该行将被覆盖。
这是来自Is a move-from vector always empty?的简短摘录?用英语 SO。在那里查看详细信息。
移动后,原始向量将为空,至少在使用标准分配器的情况下是这样。标准没有明确保证,但这是标准库的实现可以做的唯一合理的事情。
这隐含地源于以下事实:
std::swap对于向量,它不能使元素上的迭代器无效),因此,所有元素必须始终位于堆上。因此,移动操作的唯一合理行为是将原始向量留空。