Namespaces
Variants

std:: declval

From cppreference.net
Utilities library
Definido en el encabezado <utility>
template < class T >
typename std:: add_rvalue_reference < T > :: type declval ( ) noexcept ;
(desde C++11)
(hasta C++14)
(solo para uso no evaluado)
template < class T >
std:: add_rvalue_reference_t < T > declval ( ) noexcept ;
(desde C++14)
(solo para uso no evaluado)

Plantilla auxiliar para escribir expresiones que aparecen en contextos no evaluados , típicamente el operando de decltype . En contextos no evaluados, esta plantilla auxiliar convierte cualquier tipo T (que puede ser un tipo incompleto) en una expresión de ese tipo, haciendo posible usar funciones miembro de T sin necesidad de pasar por constructores.

std::declval solo puede utilizarse en contextos no evaluados y no requiere estar definido; es un error evaluar una expresión que contenga esta función. Formalmente, el programa está mal formado si esta función es odr-used .

Contenidos

Parámetros

(ninguno)

Valor de retorno

No puede ser evaluada y por lo tanto nunca retorna un valor. El tipo de retorno es T&& (se aplican las reglas de colapso de referencias) a menos que T sea (posiblemente calificado cv) void , en cuyo caso el tipo de retorno es T .

Notas

std::declval se utiliza comúnmente en plantillas donde los parámetros de plantilla aceptables pueden no tener ningún constructor en común, pero tienen la misma función miembro cuyo tipo de retorno es necesario.

Implementación posible

template<typename T>
typename std::add_rvalue_reference<T>::type declval() noexcept
{
    static_assert(false, "declval no permitido en un contexto evaluado");
}

Ejemplo

#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;     // tipo de n1 es int
    decltype(std::declval<Default>().foo()) n2 = 1;     // mismo
//  decltype(NonDefault().foo())               n3 = n1; // error: no hay constructor por defecto
    decltype(std::declval<NonDefault>().foo()) n3 = n1; // tipo de n3 es int
    std::cout << "n1 = " << n1 << '\n'
              << "n2 = " << n2 << '\n'
              << "n3 = " << n3 << '\n';
}

Salida:

n1 = 1
n2 = 1
n3 = 1

Véase también

decltype especificador (C++11) obtiene el tipo de una expresión o una entidad
(C++11) (eliminado en C++20) (C++17)
deduce el tipo de resultado de invocar un objeto invocable con un conjunto de argumentos
(plantilla de clase)