На работе у нас есть класс с дорогим конструктором, поэтому мы бы хотели, чтобы он вызывался как можно меньше раз. Мы просмотрели его использование и попытались сделать код более дружественным к RVO, так сказать.
Однако мы нашли причуду в компиляторе g ++, где не поняли, что произошло.
Пожалуйста, рассмотрите две реализации оператора +
const Imaginary Imaginary::operator+(const Imaginary& rhs) const
{
Imaginary tmp(*this);
tmp.append(rhs);
return tmp;
}
и
const Imaginary Imaginary::operator+(const Imaginary& rhs) const
{
return Imaginary(*this).append(rhs);
}
Я поместил распечатки в различные конструкторы и со следующей маленькой программой
int main(int argc, char* argv[])
{
Imaginary x(1, 1);
Imaginary y(2, 1);
Imaginary c = x + y;
return 0;
}
Я получаю эту распечатку с первой реализацией оператора +
int/int ctor
int/int ctor
Copy ctor
И я получаю следующее, когда используется второй вариант оператора +
int/int ctor
int/int ctor
Copy ctor
Copy ctor
Здесь мы видим, что g ++ может оптимизировать один вызов конструктора копирования в одном случае, но не во втором, и, к моему удивлению, ему удалось это сделать с помощью более неуклюжей реализации , в которой я сохранил это временно.
Теперь я мог бы понять это больше, если бы это было наоборот, но, по-видимому, это не так
и теперь я надеюсь, что, возможно, вы могли бы просветить меня по этому вопросу.
Вероятно, мне следует добавить это, когда мы добавляем --no-elide-constructors в качестве флага для g ++
Я получаю следующую распечатку
int/int ctor
int/int ctor
Copy ctor
Copy ctor
Copy ctor
С уважением, Маттиас