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
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.