Вот почему копирование не имеет смысла для параметров. Это действительно о реализации концепции на уровне компилятора.
Копировать elision работает, по сути, создавая возвращаемое значение на месте. Значение не копируется; он создан прямо в месте назначения. Вызывающий объект обеспечивает пространство для предполагаемого вывода, и, таким образом, в конечном счете вызывающий абонент обеспечивает возможность выбора.
Все, что внутренняя функция должна сделать для удаления копии, - это создать вывод в месте, предоставленном вызывающей стороной. Если функция может сделать это, вы получаете право на копирование. Если функция не может, тогда она будет использовать одну или несколько временных переменных для хранения промежуточных результатов, а затем скопировать / переместить это в место, предоставленное вызывающей стороной. Он все еще создается на месте, но создание вывода происходит с помощью копирования.
Таким образом, мир за пределами определенной функции не должен знать или заботиться о том, выполняет ли функция выбор. В частности, вызывающий функции не должен знать о том, как реализована функция. Это не делает ничего другого; сама функция решает, возможно ли исключение.
Хранение для параметров значения также предоставляется вызывающей стороной. Когда вы вызываете f(t)
, вызывающая сторона создает копию t
и передает ее f
. Аналогично, если S
неявно конструируется из int
, то f(5)
создаст S
из 5 и передаст его f
.
Все это делает вызывающий . Вызываемый не знает и не заботится о том, что это переменная или временная переменная; ему просто дают место в памяти стека (или регистры или что-то еще).
Теперь запомните: copy elision работает, потому что вызываемая функция создает переменную непосредственно в выходном местоположении. Поэтому, если вы пытаетесь исключить возврат из параметра значения, тогда хранилище для параметра значения также должно быть самим хранилищем вывода . Но помните: это вызывающий , который обеспечивает эту память как для параметра, так и для вывода. И поэтому, чтобы исключить выходную копию, вызывающая сторона должна встроить параметр непосредственно в output .
Чтобы сделать это, теперь вызывающий должен знать, что вызываемая функция исключит возвращаемое значение, потому что он может только вставить параметр непосредственно в вывод, если параметр будет возвращен. Обычно это не возможно на уровне компилятора, потому что вызывающая сторона не обязательно имеет реализацию функции. Если функция встроенная, то, возможно, она может работать. Но в противном случае нет.
Поэтому комитет по С ++ не стал допускать такую возможность.