Этот вопрос касается спецификации нескольких функций в стандартной библиотеке С++ 11, которые принимают свои аргументы как ссылки rvalue, но не потребляют их во всех случаях. Одним из примеров является
std::unordered_set<T>::insert(T&&)
.
Довольно ясно, что этот метод будет использовать конструктор перемещения T
для построения элемента внутри контейнера, если он еще не существует. Однако что произойдет, если элемент уже существует в контейнере? Я уверен, что нет причин для изменения объекта в случае. Тем не менее, я не нашел ничего в стандарте С++ 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. Но я не уверен, если он соответствует стандарту.