Почему `is_destructible` определяется с помощью` declval(). ~ U () `, а не` declval <U>(). ~ U () `? - PullRequest
0 голосов
/ 15 февраля 2019

По определению is_destructible (http://eel.is/c++draft/meta.unary.prop#lib:is_destructible), is_­destructible_v<T> равно true, когда:

Либо T является ссылочным типом, либо T являетсяполный тип объекта, для которого выражение declval<U&>().~U() правильно сформировано, когда рассматривается как неоцененный операнд, где U равно remove_­all_­extents_­t<T>.

Почему используется declval<U&>().~U(), а не declval<U>().~U()?

В https://cplusplus.github.io/LWG/issue2049 была добавлена ​​формулировка с declval для решения проблемы, возникшей в определении с абстрактными типами. Возможно, автор думал, что declval<U> имеет тип возвращаемого значения U, поэтомуэто не будет работать для абстрактных типов?

1 Ответ

0 голосов
/ 17 февраля 2019

Итак, я спросил Даниэля Крюглера по электронной почте, и он позволил мне опубликовать его ответ:

Хороший вопрос - хотя ответ довольно тривиален и не раскрывает никакой языковой тайны: я знал, чтоstd::declval<T>() вернул бы ссылку rvalue (и, следовательно, rvalue) в обсуждаемом контексте, но в моем воображении я хотел выразить картину перевода p->~T(), что опять же в соответствии с языком соответствует (*p).~T() ([expr.ref]), поэтому логическим следствием было изменение вызова std::declval() для генерации lvalue T, к которому был применен деструктор.

Я почти уверен, что не верил, чтоdeclval() возвращал T напрямую, эта вспомогательная функция слишком глубоко сгорела в моей голове; -)

...