std:: declval
|
Определено в заголовочном файле
<utility>
|
||
|
template
<
class
T
>
typename std:: add_rvalue_reference < T > :: type declval ( ) noexcept ; |
(начиная с C++11)
(до C++14) (только для невычисляемых контекстов) |
|
|
template
<
class
T
>
std:: add_rvalue_reference_t < T > declval ( ) noexcept ; |
(начиная с C++14)
(только для невычисляемых контекстов) |
|
Вспомогательный шаблон для написания выражений, которые появляются в
невычисляемых контекстах
, обычно в качестве операнда
decltype
. В невычисляемом контексте этот вспомогательный шаблон преобразует любой тип
T
(который может быть неполным типом) в выражение этого типа, позволяя использовать функции-члены T без необходимости обращения к конструкторам.
std::declval
может использоваться только в
невычисляемых контекстах
и не требует определения; является ошибкой вычисление выражения, содержащего эту функцию. Формально, программа является некорректной, если эта функция
ODR-используется
.
Содержание |
Параметры
(нет)
Возвращаемое значение
Не может быть вычислено и, следовательно, никогда не возвращает значение. Возвращаемый тип —
T&&
(применяются правила схлопывания ссылок), за исключением случая, когда
T
является (возможно, cv-квалифицированным)
void
, в этом случае возвращаемый тип —
T
.
Примечания
std::declval
обычно используется в шаблонах, где допустимые параметры шаблона могут не иметь общего конструктора, но имеют одинаковую функцию-член, возвращаемый тип которой требуется получить.
Возможная реализация
template<typename T> typename std::add_rvalue_reference<T>::type declval() noexcept { static_assert(false, "declval not allowed in an evaluated context"); } |
Пример
#include <iostream> #include <utility> struct Default { int foo() const { return 1; } }; struct NonDefault { NonDefault() = delete; int foo() const { return 1; } }; int main() { decltype(Default().foo()) n1 = 1; // тип n1 - int decltype(std::declval<Default>().foo()) n2 = 1; // то же самое // decltype(NonDefault().foo()) n3 = n1; // ошибка: нет конструктора по умолчанию decltype(std::declval<NonDefault>().foo()) n3 = n1; // тип n3 - int std::cout << "n1 = " << n1 << '\n' << "n2 = " << n2 << '\n' << "n3 = " << n3 << '\n'; }
Вывод:
n1 = 1 n2 = 1 n3 = 1
Смотрите также
decltype
спецификатор
(C++11)
|
получает тип выражения или сущности |
|
(C++11)
(удалён в C++20)
(C++17)
|
выводит тип результата вызова вызываемого объекта с набором аргументов
(шаблон класса) |