c++templatesc++11rvalue-reference

function template only taking rvalues


It's easy enough to write a function taking only lvalues

template <typename T>
void f(T&);

but because of universal references, writing one that only takes rvalue references isn't straight forward. Is there a way to write a generic function that only takes rvalue refs? (the return type isn't really a concern)

template <typename T>
void only_rvals(T&&);

where

int i{};
only_rvals(i); // fails to compile
only_rvals(6); // successfully compiles

Solution

  • Add a

    template<class T>
    void only_rvals(T&)=delete;
    

    overload to the universal one. It will be preferred, and generate an error if selected.

    Alternatively, SFINAE check, or a post-C++1y requires clause, or a static_assert, or a tag dispatch using is_reference or similar would all work.

    Ideally you want failure at point of call, clarity of code, clarity of diagnostic, robustness of solution, and extendable. The post-C++1y requires will eventually be best. static_assert gives a clear diagnostic (as can tag disptching, but you want a trait called is_rvalue dispatched to true_type), and SFINAE and =delete make the error occur at the call site. =delete does not scale to more arguments, SFINAE is fragile.

    SFINAE and requires allows alternative overloads to be used. This may or may not be desired.