Правильное применение const?
Параметры функции, объявленные как const ссылки, могут инициализироваться результатом выражения (rvalue), а обычные ссылки, без const - только присваиваемому выражению (lvalue). В С++11 появились также rvalue ссылки, которые могут быть изменяемыми. Сложные объекты лучше передавать в функции по ссылкам (или указателям), чтобы избегать копирования.
Значит если параметр передаётся по ссылке, то ссылка с const может быть входным параметром функции, а без const - скорее всего выходным (или двунаправленным, который передаётся в функцию и там модифицируется, и служит результатом выполнения). Параметр по ссылке без const может быть входным, но это неудобно - в нём нельзя передать выражение, а только переменную (или в общем случае lvalue). И ещё это сбивает использующих функцию программистов с толку, наводя их на мысль, что параметр по ссылке должен модифицироваться внутри вызываемой функции.

Сразу понятно назначение параметров, какой параметр входной, какой выходной. Параметр по значению всегда входной, по указателю - аналогично ссылке, с const только входной, без const скорее всего выходной (но не обязательно).
rvalue ссылки нужны в том случае, если нужно сохранить объект, переданный в функцию, без копирования (объект по const ссылке пришлось бы скопировать внутри функции, а это неоптимально). Параметр по rvalue ссылке - тоже входной параметр функции, как и по const ссылке.
const (в Java final) нужно использовать везде, где это возможно.

В некоторых языках даже сделали val и var для того, чтобы сравнять эти два случая, и не было повода писать var (мутабельный) вместо val(иммутабельный).
А в Rust даже сделали ключевое слово mut, по сути инвертировав const и сделав его умолчанием.

Всё это нужно, потому что с неизменяемыми данными работать проще. Сокращается количество вариантов использования. Увеличивается надёжность.