decltype
specifier
(since C++11)
Inspecciona el tipo declarado de una entidad o el tipo y categoría de valor de una expresión.
Contenidos |
Sintaxis
decltype (
entidad
)
|
(1) | ||||||||
decltype (
expresión
)
|
(2) | ||||||||
Explicación
|
Si el argumento es una id-expression sin paréntesis que nombra un structured binding , entonces decltype produce el tipo referenciado (descrito en la especificación de la declaración de enlace estructurado). |
(desde C++17) |
|
Si el argumento es una id-expression sin paréntesis que nombra un constant template parameter , entonces decltype produce el tipo del parámetro de plantilla (después de realizar cualquier deducción de tipo necesaria si el parámetro de plantilla se declara con un tipo de marcador de posición). El tipo es no-const incluso si la entidad es un objeto de parámetro de plantilla (que es un objeto const). |
(desde C++20) |
T
, y
|
Si expresión es una llamada a función que retorna un prvalue de tipo clase o es una expresión coma cuyo operando derecho es dicha llamada a función, no se introduce un objeto temporal para ese prvalue. |
(hasta C++17) |
|
Si expresión es un prvalue distinto de una invocación inmediata (posiblemente entre paréntesis) (desde C++20) , no se materializa un objeto temporal a partir de ese prvalue: dicho prvalue no tiene objeto resultado. |
(desde C++17) |
Tenga en cuenta que si el nombre de un objeto está entre paréntesis, se trata como una expresión lvalue ordinaria, por lo que decltype ( x ) y decltype ( ( x ) ) suelen ser tipos diferentes.
decltype
es útil al declarar tipos que son difíciles o imposibles de declarar usando notación estándar, como tipos relacionados con lambdas o tipos que dependen de parámetros de plantilla.
Notas
| Macro de prueba de características | Valor | Std | Característica |
|---|---|---|---|
__cpp_decltype
|
200707L
|
(C++11) | decltype |
Palabras clave
Ejemplo
#include <cassert> #include <iostream> #include <type_traits> struct A { double x; }; const A* a; decltype(a->x) y; // tipo de y es double (tipo declarado) decltype((a->x)) z = y; // tipo de z es const double& (expresión lvalue) template<typename T, typename U> auto add(T t, U u) -> decltype(t + u) // el tipo de retorno depende de los parámetros de plantilla // el tipo de retorno puede deducirse desde C++14 { return t + u; } const int& getRef(const int* p) { return *p; } static_assert(std::is_same_v<decltype(getRef), const int&(const int*)>); auto getRefFwdBad(const int* p) { return getRef(p); } static_assert(std::is_same_v<decltype(getRefFwdBad), int(const int*)>, "Solo retornar auto no es un reenvío perfecto."); decltype(auto) getRefFwdGood(const int* p) { return getRef(p); } static_assert(std::is_same_v<decltype(getRefFwdGood), const int&(const int*)>, "Retornar decltype(auto) reenvía perfectamente el tipo de retorno."); // Alternativamente: auto getRefFwdGood1(const int* p) -> decltype(getRef(p)) { return getRef(p); } static_assert(std::is_same_v<decltype(getRefFwdGood1), const int&(const int*)>, "Retornar decltype(expresión de retorno) también reenvía perfectamente el tipo de retorno."); int main() { int i = 33; decltype(i) j = i * 2; static_assert(std::is_same_v<decltype(i), decltype(j)>); assert(i == 33 && 66 == j); auto f = [i](int av, int bv) -> int { return av * bv + i; }; auto h = [i](int av, int bv) -> int { return av * bv + i; }; static_assert(!std::is_same_v<decltype(f), decltype(h)>, "El tipo de una función lambda es único y sin nombre"); decltype(f) g = f; std::cout << f(3, 3) << ' ' << g(3, 3) << '\n'; }
Salida:
42 42
Referencias
| Contenido extendido |
|---|
|
|
Esta sección está incompleta
Razón: Requiere corrección. Ver: Talk: Wrong References . |
Véase también
auto
especificador
(C++11)
|
especifica un tipo deducido a partir de una expresión |
|
(C++11)
|
obtiene una referencia a un objeto del argumento de tipo de plantilla para usar en un contexto no evaluado
(plantilla de función) |
|
(C++11)
|
verifica si dos tipos son iguales
(plantilla de clase) |
|
documentación de C
para
typeof
|
|