c++c++11perfect-forwardingforwarding-reference

Is there a way to describe that parameters are not mutated through a forwarding reference?


Among the many benefits of const qualification is to make an API more understandable, example:

template<typename T> int function1(T const& in);
// clearly, the input won’t change through function1

With the introduction of rvalue references, one can benefit from perfect forwarding but often const qualifiers are removed, example:

template<typename T> int function2(T&& in);
// can explicitly forward the input if it's an rvalue

Apart from documentation, is there a good way to describe that function2 won’t change its input?


Solution

  • template<typename T> int function2(T&& in);
    // can explicitly forward the input if it's an rvalue
    

    Apart from documentation, is there a good way to describe that function2 won’t change its input?

    Yes. Stick with the C++03 solution:

    template<typename T> int function1(T const& in);
    // clearly, the input won’t change through function1
    

    The benefits of perfect forwarding are that you don't want to assume if something is const or non-const, lvalue or rvalue. If you want to enforce that something is not modified (i.e. that it is const), then explicitly say so by adding const.

    You could do this:

    template<typename T> int function1(T const&& in);
    // clearly, the input won’t change through function1
    

    However everyone who read your code would wonder why you've used rvalue references. And function1 would cease to accept lvalues. Just use const & instead and everyone will understand. It is a simple and well understood idiom.

    You don't want to perfectly forward. You want to enforce immutability.