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.

Original source

Related problems