Что ж, альтернативный способ обойти копирование - использовать идиому «возвращаемый параметр» вместо использования возвращаемого значения функции
void getAllAbove(Triangle* t, std::list<Triangle*>& result);
Вместо формирования результата «в стеке», как выТеперь создайте его непосредственно в параметре result
(т. е. в списке получателей, который вы передаете от вызывающего абонента).
Что касается исходного кода, будет ли копирование выполнено или нет, зависит от возможностейтвой компилятор.
С самой абстрактной точки зрения ваш код на самом деле имеет две копии.(И да, это полноценные копии, когда все содержимое списка тщательно дублируется в другом списке, элемент за элементом.) Во-первых, именованный объект списка, который вы создаете в стеке внутри вашей функции, копируется в безымянный временный объекткоторый содержит возвращаемое значение функции.Затем временный объект копируется в конечный объект получателя в вызывающем коде.Большинство компиляторов смогут исключить одно из этих копий (исключить промежуточное временное, как это разрешено спецификацией C ++ 98).
Чтобы исключить второе, компилятор должен иметь возможность выполнять так называемую оптимизацию именованных возвращаемых значений (как это разрешено спецификацией C ++ 03).Компилятор, который поддерживает оптимизацию именованных возвращаемых значений, должен по сути неявно преобразовывать интерфейс вашей функции в эквивалент вышеупомянутой идиомы «возвращаемый параметр».Я ожидаю, что GCC сможет это сделать.Попробуйте и посмотрите, что получится.