"forwarding references" is in quotes because const
-qualified forwarding references aren't actually forwarding references, but I wanted to make it clear that I am specifically referring to function templates.
Take the following test functions (code is duplicated to avoid :
#include <iostream>
#include <type_traits>
#include <typeinfo>
using namespace std;
template <typename T, typename U> void print_types() {
cout << (is_const_v<remove_reference_t<T>> ? "const " : "")
<< typeid(T).name()
<< (is_rvalue_reference_v<T> ? " &&"
: is_lvalue_reference_v<T> ? " &"
: "")
<< ", " << (is_const_v<remove_reference_t<U>> ? "const " : "")
<< typeid(U).name()
<< (is_rvalue_reference_v<U> ? " &&"
: is_lvalue_reference_v<U> ? " &"
: "")
<< endl;
}
template <typename T> void print_rvalue_reference(T &&t) {
print_types<T, decltype(t)>();
}
template <typename T> void print_const_rvalue_reference(const T &&t) {
print_types<T, decltype(t)>();
}
int main() {
int i = 1;
const int j = 1;
print_rvalue_reference(1); // int, int &&
print_rvalue_reference(i); // int &, int &
print_rvalue_reference(j); // const int &, const int &
print_const_rvalue_reference(1); // int, const int &&
print_const_rvalue_reference(i); // error
print_const_rvalue_reference(j); // error
}
First, I wanted to note that print_rvalue_reference(j)
only works because print_rvalue_reference
never uses t
in a non-const
context. If this were not the case, the template instantiation would fail.
I am confused why the last two calls in main
cause errors during compilation. Reference collapsing allows using T = int &; const T &&
to become int &
and using T = const int &; const T &&
to become const int &
, which means print_const_rvalue_reference<int &>(i)
and print_const_rvalue_reference<const int &>(j)
are valid.
Why does print_const_rvalue_reference(j)
deduce T to be int
instead of const int &
when print_rvalue_reference(j)
does deduce T to be const int &
? Are (true) forwarding references special-cased to yield int &
instead of int
as part of its deduction guide?
Aucun commentaire:
Enregistrer un commentaire