Хотя я на самом деле не проверял никаких компиляторов для этого, я сомневаюсь в этом. Вы предполагаете, что передача константной ссылки неотличима от простой передачи значения, но это не так, и компилятор не должен предполагать, что это так.
Поскольку ссылка является константной, ваша функция не может изменить значение через нее, но другие части кода могут иметь доступ к исходной (неконстантной) переменной и могут изменять ее. Ваша функция может вызывать какую-то другую функцию, которая, например, изменяет ее, или одновременно может выполняться другой поток, выполняющий это.
Если что-то еще изменит эту исходную переменную, ваша функция с ее ссылкой должна увидеть новое значение. Если компилятор заменит ссылку на копию, функция все равно увидит старое значение.
Возможно, вас заинтересует библиотека вызовов Boost . Он предоставляет тип шаблона call_traits<T>::param_type
, который является константной ссылкой для «больших» типов, которые вы не хотите копировать, и значение для «малых» типов, где копирование будет более эффективным. По сути, то, что вы хотите, чтобы компилятор делал неявно, вы можете делать явно с вашим кодом.