how is this sizeof expression evaluated? and why it is called that way?
c++
Solution
In order to apply `sizeof()`, you need a complete type. But returning a complete type isn't a requirement of assignability, hence:
sizeof((std::declval<X>() = std::declval<Y>(), true))
~~~~~~~~~~~~~~~~~~ expr ~~~~~~~~~~~~~~~~~~~~~
if the assignment is valid for those two types, then we have `sizeof(expr)` where the type of `expr` is `bool` (because `true`). So if the assignment is valid, we get some real `size`. Otherwise, substitution failure.
But this is an unnecessarily cryptic way of writing this code. Moreover, it's not even correct because I could write a type like:
struct Evil {
template <class T> Evil operator=(T&& ); // assignable from anything
void operator,(bool); // mwahahaha
};
and now your `sizeof()` still doesn't work.
Instead, prefer simply:
class = decltype(std::declval<X>() = std::declval<Y>())
This accomplishes the same result - either substitution failure or not - without needed to care at all about what the type of the result is or to handle special cases.
Problem
I came across with this code in an `std::optional` implementation : ``` template <class T, class U> struct is_assignable { template <class X, class Y> constexpr static bool has_assign(...) { return false; } template <class X, class Y, size_t S = sizeof((std::declval<X>() = std::declval<Y>(), true)) > // the comma operator is necessary for the cases where operator= returns void constexpr static bool has_assign(bool) { return true; } constexpr static bool value = has_assign<T, U>(true); }; ``` The part that I cant understand how it works or how it is evaluated is `size_t S = sizeof((std::declval<X>() = std::declval<Y>(), true))` I know that if the assign operation fails it will fall back to the first definition of has_assign that returns false, but i don't know why it has the `, true)` part. I did some test with structs that returns void on the assign operator and removing the `, true` part in `sizeof` gives me the same results.