Для чего T std::declval <T> () не имеет функции сопоставления?
Я был удивлен, обнаружив, что для некоторых T
, decltype(std::declval<T>())
не законно:
#include <utility>
template<typename T>
using Alias = decltype(std::declval<T>());
// as expected
using A1 = Alias<int>;
using A2 = Alias<int(int)>;
// error: no matching function for call to 'declval<...>()'
using A3 = Alias<int(int) const>;
using A4 = Alias<int(int) volatile>;
using A5 = Alias<int(int) &>;
using A6 = Alias<int(int) &&>;
// and all combinations of the above
cppreference, похоже, не указывает на то, что эта ошибка ожидается.
Есть ли другие типы, для которых declval<T>
нельзя использовать? Где это определяется в спецификации?
1 ответ
Per [declval], подписьdeclval
является:
template <class T>
add_rvalue_reference_t<T> declval() noexcept;
Следовательно, вызов является некорректным, если add_rvalue_reference_t<T>
не может использоваться в качестве спецификатора возвращаемого типа.
У квалифицированных типов функций есть особое правило:
Тип функции с cv-qualifier-seq или ref-qualifier (включая тип с именем typedef-name ([dcl.typedef], [temp.param])) должен отображаться только как:
(6.1) тип функции для нестатической функции-члена,
(6.2) тип функции, на который ссылается указатель на член,
(6.3) тип функции верхнего уровня объявления функции typedef или объявления псевдонима,
(6.4) идентификатор типа в аргументе по умолчанию параметра типа, или
(6.5) идентификатор типа аргумента-шаблона для параметра-типа ([temp.arg.type]).
Они не могут быть спецификатором возвращаемого типа.
Просматривая типы, я почти уверен, что квалифицированные типы функций - единственный случай.