Пространства имён
Варианты
Действия

std::declval

Материал из cppreference.com
 
 
Библиотека утилит
Языковая поддержка
Поддержка типов (базовые типы, RTTI)
Макросы тестирования функциональности библиотеки (C++20)    
Управление динамической памятью
Программные утилиты
Поддержка сопрограмм (C++20)
Вариативные функции
Трёхстороннее сравнение (C++20)
(C++20)
(C++20)(C++20)(C++20)(C++20)(C++20)(C++20)
Общие утилиты
Дата и время
Функциональные объекты
Библиотека форматирования (C++20)
(C++11)
Операторы отношения (устарело в C++20)
Целочисленные функции сравнения
(C++20)(C++20)(C++20)    
(C++20)
Операции обмена и типа
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
Общие лексические типы
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)
Элементарные преобразования строк
(C++17)
(C++17)
 
<tbody> </tbody>
Определено в заголовочном файле <utility>
template<class T> typename std::add_rvalue_reference<T>::type declval() noexcept;
(начиная с C++11)

Преобразует любой тип T в ссылочный тип, позволяя использовать функции-элементы в операнде спецификатора decltype без необходимости перехода через конструкторы.

std::declval обычно используется в шаблонах, где допустимые параметры шаблона могут не иметь общего конструктора, но могут иметь одну и ту же функцию-элемент, тип возвращаемого значения которой необходим.

Обратите внимание, что std::declval может использоваться только в невычисленных контекстах и не требует определения; вычисление выражения, содержащего эту функцию, является ошибкой. Формально программа некорректна, если эта функция используется odr.

Параметры

(нет)

Возвращаемое значение

Не может быть вызвана и поэтому никогда не возвращает значение. Тип возвращаемого значения T&&, если только T не является (возможно, cv-квалифицированным) void, и в этом случае тип возвращаемого значения T.

Возможная реализация

template<typename T>
typename std::add_rvalue_reference<T>::type declval() noexcept
{
    static_assert(false, "declval не допускается в оцениваемом контексте");
}

Пример

#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(NonDefault().foo()) n2 = n1; // ошибка: нет конструктора по умолчанию
    decltype(std::declval<NonDefault>().foo()) n2 = n1; // тип n2 это int
    std::cout << "n1 = " << n1 << '\n'
              << "n2 = " << n2 << '\n';
}

Вывод:

n1 = 1
n2 = 1

Смотрите также

спецификатор decltype(C++11) получает тип выражения или сущности[править]
(C++11)(удалено в C++20)(C++17)
выводит тип результата вызова вызываемого объекта с набором аргументов
(шаблон класса) [править]