这个问题是关于C++11标准库中几个函数的规范,这些函数将它们的参数作为右值引用,但并不是在所有情况下都使用它们。std::unordered_set<T>::insert(T&&)
就是一个例子。
很明显,此方法将使用T
的move构造函数在容器中构造元素(如果元素尚不存在)。但是,如果该元素已经存在于容器中,会发生什么呢?我非常确定没有理由改变这种情况下的对象。然而,我在C++11标准中找不到任何支持我的声明的东西。
这里有一个例子来说明为什么这可能很有趣。下面的代码从std::cin中读取行,并删除第一次出现的重复行。
std::unordered_set<std::string> seen;
std::string line;
while (getline(std::cin, line)) {
bool inserted = seen.insert(std::move(line)).second;
if (!inserted) {
/* Is it safe to use line here, i.e. can I assume that the
* insert operation hasn't changed the string object, because
* the string already exists, so there is no need to consume it. */
std::cout << line << '\n';
}
}
显然,这个例子适用于GCC 4.7。但我不确定,根据标准,它是否正确。
发布于 2012-04-06 21:02:54
这是正确的。
当然,-when处理哲学-任何事情都可以质疑,但编译器必须以某种方式做到这一点。
设计师的选择是让-to执行一项行动--必须有一个地方可以去。如果没有这样的地方,移动就不会发生。
请注意,无论哪个函数使用&&,它都假定参数是“临时的”:如果它没有“窃取”数据,那么临时参数将在表达式的末尾被销毁。如果临时被强制(通过std::move),对象在任何情况下都会留在那里,直到被它自己的作用域销毁。不管里面有没有原始数据。
https://stackoverflow.com/questions/10043716
复制相似问题