2

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`
}
T.C.
  • 133,968
  • 17
  • 288
  • 421
Billy ONeal
  • 104,103
  • 58
  • 317
  • 552

0 Answers0