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; // type of n1 is int
decltype(std::declval<Default>().foo()) n2 = 1; // same
// decltype(NonDefault().foo()) n3 = n1; // error: no default constructor
decltype(std::declval<NonDefault>().foo()) n3 = n1; // type of n3 is 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) | выводит тип результата вызова вызываемого объекта с набором аргументов (шаблон класса) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/utility/declval