std::declval
| Определено в заголовочном файле <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) |
выводит тип результата вызова вызываемого объекта с набором аргументов (шаблон класса) |