Здесь - это статья, которую я использую в качестве ссылки, которая в конечном итоге была упомянута в этом SO-ответе .
Автор приводит два примера:
Пример 1:
std::vector<std::string>
sorted(std::vector<std::string> names)
{
std::sort(names);
return names;
}
// names is an lvalue; a copy is required so we don't modify names
std::vector<std::string> sorted_names1 = sorted( names );
// get_names() is an rvalue expression; we can omit the copy!
std::vector<std::string> sorted_names2 = sorted( get_names() );
Пример 2:
std::vector<std::string>
sorted2(std::vector<std::string> const& names) // names passed by reference
{
std::vector<std::string> r(names); // and explicitly copied
std::sort(r);
return r;
}
Тогда говорят:
Хотя отсортированные и отсортированные2 на первый взгляд кажутся идентичными,Там может быть огромная разница в производительности, если компилятор копирует elision. Даже если фактическим аргументом для sorted2 является rvalue, источником копии, names, является lvalue, поэтому копия не может быть оптимизирована. В некотором смысле, elision copy является жертвой отдельной модели компиляции: внутри тела sorted2 нет информации о том, является ли фактический аргумент функции r-значением;снаружи, на сайте вызова, нет никаких признаков того, что копия аргумента в конечном итоге будет сделана.
Мой вопрос прост: почему компилятор не может использовать elision для копирования во втором примере, но он можетв первом?
А как насчет передачи по значению, а отличий их отличает? names
названо в обоих случаях, поэтому я предполагаю, что мы также создаем lvalue в обоих случаях.