Пожалуйста, взгляните на эту глупую функцию, которая должна только проиллюстрировать проблему и упрощение реального кода:
struct A;
A create(bool first){
A f(21), s(42);
if(first)
return f;
else
return s;
}
Я понимаю, потому что не ясно, какой объект будет возвращен во времяПри компиляции мы не можем ожидать, что оптимизация возвращаемого значения (RVO) будет выполняться всегда.
Однако можно ожидать, что RVO будет выполняться в 50% случаев (при условии равномерного распределения для true
/ * 1007).* из-за отсутствия дополнительной информации): просто решите, для какого случая следует выполнить RVO (first==true
или first==false
), и примените его к этому значению параметра, принимая, что в другом случае должен быть вызван конструктор копирования.
Тем не менее, это «частичное RVO» подходит не для всех компиляторов, с которыми я могу справиться (см. Прямую трансляцию с gcc , clang и MSVC ) - в обоих случаях (то есть first==true
или first==false
) используется конструктор копирования, а не опускается.
Есть ли что-то, что делает "частичное RVO" в приведенном выше случае недействительнымid или это маловероятный случай пропущенной оптимизации всеми компиляторами?
Полная программа:
#include <iostream>
struct A{
int val;
A(int val_):val(val_){}
A(const A&o):val(o.val){
std::cout<<"copying: "<<val<<"\n";
}
};
A create(bool first){
A f(21), s(42);
if(first)
return f;
else
return s;
}
int main(){
std::cout<<"With true: ";
create(true);
std::cout<<"With false: ";
create(false);
}