I am trying to figure out how to interpret declval<_Dest>() = declval<_Src>() in the implementation of is_assignable.
declval turns a type into a reference. Given that, I translate the expression into one of the following four possibilities:
- _Dest&& = _Src&&
- _Dest&& = _Src&
- _Dest& = _Src&&
- _Dest& = _Src&
I then created two helper functions.
template <typename T> T rvalue();
template <typename T> T& lvalue();
My understanding is the four expressions can be realized by using the template functions.
- _Dest&& = _Src&& -----> rvalue<_Dest>() = rvalue<_Src>()
Same goes for the other three.
Then I simulated decltype(declval<_Dest>() = declval<_Src>(), ..) by compiling the templated function version of each of the possibilities for three pairs of concrete types.
- _Dest=int, _Src=int. Compiler accepts #3 and #4. is_assignable returned true for #3 and #4. They agreed.
- _Dest=int, _Src=double. Same result as
- _Dest=double, _Src=int. For this one, the compiler and is_assignable didn't agree. Compiler again does not like assigning to rvalues. However, is_assignable returns true for all four possibilities.
My questions are
- Did I interpret declval<_Dest>() = declval<_Src>() correctly? In order words, does this really translate into the four possibilities. If yes, can each one be mapped to a templated function expression?
- Why the compiler and is_assignable disagree on the _Dest=double, _Src=int case?
Thanks.