To pytanie dotyczy specyfikacji kilku funkcji w bibliotece standardowej C++ 11, które przyjmują swoje argumenty jako odniesienia rvalue, ale nie konsumuj je we wszystkich przypadkach. Jednym z przykładów jest std::unordered_set<T>::insert(T&&)
.std :: unordered_set <T> :: insert (T &&): argument zostanie przeniesiony, jeśli istnieje
Jest całkiem jasne, że ta metoda użyje konstruktora ruchu z T
do skonstruowania elementu w kontenerze, jeśli jeszcze nie istnieje. Co się jednak stanie, jeśli element już istnieje w kontenerze? Jestem prawie pewien, że nie ma powodu, aby zmienić przedmiot w tej sprawie. Jednak nie znalazłem nic w standardzie C++ 11 wspierającym moje roszczenie.
Oto przykład pokazujący, dlaczego może to być interesujące. Poniższy kod odczytuje linie ze std :: cin i usuwa pierwsze wystąpienie duplikatów linii.
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';
}
}
Wygląda na to, że ten przykład działa z GCC 4.7. Ale nie jestem pewien, czy jest to zgodne z normą.
Byłoby niewydajne, aby przenieść, gdy nie jest wymagane, ale tylko standard ma znaczenie. Dobre pytanie! –
'std :: cout << linia << '\ n';' Zwróć uwagę, że standard nie mówi, że to zadziała. "linia" pozostanie w "prawidłowym stanie o nieokreślonej wartości". Zamiast tego należy zaznaczyć opcję 'line.empty()'. –
To wszystko brzmi, jakby to był świetny raport o wadzie. –