Consider the following:
template<class T>
void Destroy(T&& t) {
// Do something dangerous to `t`
}
The author intends write a function that accepts any rvalue and does something that destroys it. However, that's not what happens here -- if Destroy
is called with a lvalue U
, T
is deduced as U&
, and t
has type U&
after reference collapsing. That means it compiles for lvalues, when the author wanted such calls to fail to compile.
One can't disable the reference collapsing (e.g.
template<class T>
void Destroy(typename remove_reference<T>::type&& t) {
// Do something dangerous to `t`
}
) because the ::
disables template argument deduction completely.
Is the only way out here to static_assert
?
template<class T>
void Destroy(T&& t) {
static_assert(!is_lvalue_reference_v<T>, "Don't call with lvalues!");
// Do something dangerous to `t`
}