Namespaces
Variants

std::declval

De es.cppreference.net
 
 
Biblioteca de utilidades
Soporte de lenguaje
Soporte de tipos (tipos básicos, RTTI)
Macros de prueba de características de biblioteca (C++20)
Utilidades de programa
Funciones variádicas
Soporte de corrutinas (C++20)
Soporte de contratos (C++26)
Comparación a tres vías
(C++20)
(C++20) (C++20) (C++20)    
(C++20) (C++20) (C++20)

Utilidades generales
Operadores relacionales (obsoleto en C++20)
 
Definido en el encabezado <utility>
template< class T >
typename std::add_rvalue_reference<T>::type declval() noexcept;
(desde C++11)
(hasta C++14)
(solo sin evaluar)
template< class T >
std::add_rvalue_reference_t<T> declval() noexcept;
(desde C++14)
(solo sin evaluar)

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

std::declval solo puede ser usado en contextos no evaluados y no se requiere que esté definida; es un error evaluar una expresión que contenga esta función. Formalmente, el programa está mal formado si esta función es odr-usada.

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)