Для чего 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]).

Они не могут быть спецификатором возвращаемого типа.

Просматривая типы, я почти уверен, что квалифицированные типы функций - единственный случай.

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