На работе у нас есть класс с дорогим конструктором, поэтому мы хотели бы, чтобы его вызывали как можно меньше. Мы рассмотрели его использование и попытались сделать код более дружественным 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
И я получаю следующее, когда используется второй вариант operator +
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
С уважением, Маттиас