Consider we need to implement a function f
with a templated argument T t
. The function should not copy t
and accept both rvalues
and lvalues
, therefore two implementations are possible:
template <class T>
void f(const T& t) { ... }
template <class T>
void f(T&& t) { ... }
If we want to change t
inside of f
or need to preserve the value category, we have to use the second version. So by this line of thought when and why would we go for the first option?
You'll mainly go for the first option when you want to give strong guarantee to the clients of your function that t
won't be changed inside of f
. Although you can drop the const
qualifier and still not modify t
, it's considered good practice and good interface design to qualify as const
a parameter if you don't change it's referred to value inside a function, plus it helps the compiler to optimize the code better.
As an extra, know that you can use const_cast
to hack around the type safety of const
if you really must, but recall that you're doing exactly that: getting rid of the type safety. Avoid this at all cost.
And lastly, a const
qualifier doesn't prevent copying, you can easily do something like:
int main()
{
const int a = 3;
int b = a; // a is copied to b
}