Для чего T не имеет `std :: declval <T>()` соответствующей функции? - PullRequest
3 голосов
/ 06 октября 2019

Я был удивлен, обнаружив, что для некоторых 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 Ответ

5 голосов
/ 06 октября 2019

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]).

Tэй не может быть спецификатором типа возвращаемого значения.

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

...