Следующий код запускает статическое утверждение на libstdС++:
#include <utility>
using t = decltype(std::declval<const void>);
Должен ли он?
Мотивация для этого вопроса:
Следующая реализация declval
предложенная Эриком Ниблером (которая, по-видимому, является оптимизацией времени компиляции)
template<typename _Tp, typename _Up = _Tp&&>
_Up __declval(int);
template<typename _Tp>
_Tp __declval(long);
template<typename _Tp>
auto declval() noexcept -> decltype(__declval<_Tp>(0));
будет сомнительным, если пользователь может юридически наблюдать тип std::declval<const void>
. Подпись в стандартном
template <class T>
add_rvalue_reference_t<T> declval() noexcept;
приводит к типу const void ()
(или const void () noexcept
в С++ 17), тогда как предлагаемая версия приводит к типу void ()
(или void () noexcept
).