Is there a reason declval returns add_rvalue_reference instead of add_lvalue_reference

With add_rvalue_reference: declval<Foo>() is of type Foo&&. declval<Foo&>() is of type Foo& (reference collapsing: “Foo& &&” collapses to Foo&). declval<Foo&&>() is of type Foo&& (reference collapsing: “Foo&& &&” collapses to Foo&&). With add_lvalue_reference: declval<Foo>() would be of type Foo&. declval<Foo&>() would be of type Foo& (reference collapsing: “Foo& &” collapses to Foo&). declval<Foo&&>() would be … Read more

Why does the implementation of declval in libstdc++-v3 look so complicated?

std::declval is actually: template<class T> typename std::add_rvalue_reference<T>::type declval() noexcept; Where std::add_rvalue_reference<T> is usually T&&, except in cases where that is invalid (Like if T = void or T = int() const), where it is just T. The main difference is that functions cannot return arrays, but can return array references like U(&&)[] or U(&&)[N]. The … Read more