std::declval и неоцененные выражения

Со ссылкой на следующий пример в Предложении поддержки стандартной библиотеки для идиомы обнаружения C++:

// primary template handles types that do not support pre-increment
template< class, class = void_t<> >
struct
has_pre_increment_member : false_type { };

// specialization recognizes types that do support pre-increment
template< class T >
struct
has_pre_increment_member<T, void_t<decltype( ++declval<T&>() )>> : true_type { };

как выглядит выражение ++declval<T&>() классифицировать как неоцененный?

В вышеизложенном, предполагая declval() возвращается T& как обсуждалось в разделе Есть ли причина, по которой declval возвращает add_rvalue_reference вместо add_lvalue_reference, не является результатом выражения ++T& (приводит к ++declval<T&>) стать одр-использованным, а не оцененным? Согласно использованию ODR:

ссылка используется odr, если она используется, а ее референт не известен во время компиляции;

В вышеупомянутом случае референт не известен во время компиляции? В таком случае, как ссылка может быть использована с declval() на первом месте?

1 ответ

как выглядит выражение ++declval<T&>() классифицировать как неоцененный?

Потому что это внутри decltype():

Операнд decltype Спецификатор является неоцененным операндом.

Функция, переменная, структурированная привязка, оператор присваивания или конструктор и т. Д. Должны присутствовать в потенциально вычисляемом выражении, чтобы их можно было использовать в odr. decltype() не соответствует этим критериям.

Другие вопросы по тегам