c++forwarding-referenceconst-reference

C++ When to use const Reference over Forwarding Reference


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?


Solution

  • 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
    }