为什么 is_destructible 是使用 declval<U&>().~U() 而不是 declval<U>().~U() 定义的?

Why is `is_­destructible` defined using `declval<U&>().~U()` and not `declval<U>().~U()`?

根据 is_destructible (http://eel.is/c++draft/meta.unary.prop#lib:is_destructible) 的定义,is_­destructible_v<T>true 时:

Either T is a reference type, or T is a complete object type for which the expression declval<U&>().~U() is well-formed when treated as an unevaluated operand, where U is remove_­all_­extents_­t<T>.

为什么它使用 declval<U&>().~U() 而不是 declval<U>().~U()

https://cplusplus.github.io/LWG/issue2049 中添加了 declval 的措辞,以解决定义中抽象类型的问题。也许作者在想 declval<U> 有 return 类型 U 所以它不适用于抽象类型?

所以我通过电子邮件询问了 Daniel Krügler,他允许我发布他的答案:

Good question - albeit the answer is rather trivial and doesn't reveal any language secret: I was aware that std::declval<T>() would return an rvalue reference (and thus an rvalue) in the discussed context, but in my mental imagination I wanted to express the picture of translating p->~T(), which again according to the language corresponds to (*p).~T() ([expr.ref]), so the logical consequence was to change the std::declval() call to generate an lvalue of T where the destructor was applied to.

I'm pretty sure that I didn't believe that declval() was returning the T directly, this helper function was too deeply burned into my mind ;-)