std:: is_function
|
Definido en el encabezado
<type_traits>
|
||
|
template
<
class
T
>
struct is_function ; |
(desde C++11) | |
std::is_function
es un
UnaryTypeTrait
.
Comprueba si
T
es un tipo función. Tipos como
std::
function
, lambdas, clases con
operator()
sobrecargado y punteros a funciones no se consideran tipos función. Proporciona la constante miembro
value
que es igual a
true
si
T
es un tipo función. De lo contrario,
value
es igual a
false
.
Si el programa añade especializaciones para
std::is_function
o
std::is_function_v
, el comportamiento es indefinido.
Contenidos |
Parámetros de plantilla
| T | - | un tipo a verificar |
Plantilla de variable auxiliar
|
template
<
class
T
>
constexpr bool is_function_v = is_function < T > :: value ; |
(desde C++17) | |
Heredado de std:: integral_constant
Constantes miembro
|
value
[static]
|
true
si
T
es un tipo función,
false
en caso contrario
(constante miembro pública estática) |
Funciones miembro
|
operator bool
|
convierte el objeto a
bool
, devuelve
value
(función miembro pública) |
|
operator()
(C++14)
|
devuelve
value
(función miembro pública) |
Tipos miembro
| Tipo | Definición |
value_type
|
bool |
type
|
std:: integral_constant < bool , value > |
Notas
std::is_function
puede implementarse de formas mucho más simples. Las implementaciones similares a la siguiente son utilizadas por nuevas versiones de
libc++
,
libstdc++
y
MS STL
:
template<class T> struct is_function : std::integral_constant< bool, !std::is_const<const T>::value && !std::is_reference<T>::value > {};
La implementación que se muestra a continuación tiene fines pedagógicos, ya que exhibe la miríada de tipos de funciones.
Implementación posible
// plantilla principal template<class> struct is_function : std::false_type {}; // especialización para funciones regulares template<class Ret, class... Args> struct is_function<Ret(Args...)> : std::true_type {}; // especialización para funciones variádicas como std::printf template<class Ret, class... Args> struct is_function<Ret(Args......)> : std::true_type {}; // especialización para tipos de función que tienen calificadores cv template<class Ret, class... Args> struct is_function<Ret(Args...) const> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) volatile> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const volatile> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) volatile> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const volatile> : std::true_type {}; // especialización para tipos de función que tienen calificadores de referencia template<class Ret, class... Args> struct is_function<Ret(Args...) &> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const &> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) volatile &> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const volatile &> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) &> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const &> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) volatile &> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const volatile &> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) &&> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const &&> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) volatile &&> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const volatile &&> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) &&> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const &&> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) volatile &&> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const volatile &&> : std::true_type {}; // especializaciones para las versiones noexcept de todas las anteriores (C++17 y posteriores) template<class Ret, class... Args> struct is_function<Ret(Args...) noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) volatile noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const volatile noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) volatile noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const volatile noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) & noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const & noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) volatile & noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const volatile & noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) & noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const & noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) volatile & noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const volatile & noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) && noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const && noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) volatile && noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args...) const volatile && noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) && noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const && noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) volatile && noexcept> : std::true_type {}; template<class Ret, class... Args> struct is_function<Ret(Args......) const volatile && noexcept> : std::true_type {}; |
Ejemplo
#include <functional> #include <type_traits> int f(); static_assert(std::is_function_v<decltype(f)>); static_assert(std::is_function_v<int(int)>); static_assert(!std::is_function_v<int>); static_assert(!std::is_function_v<decltype([]{})>); static_assert(!std::is_function_v<std::function<void()>>); struct O { void operator()() {} }; static_assert(std::is_function_v<O()>); struct A { static int foo(); int fun() const&; }; static_assert(!std::is_function_v<A>); static_assert(std::is_function_v<decltype(A::foo)>); static_assert(!std::is_function_v<decltype(&A::fun)>); template<typename> struct PM_traits {}; template<class T, class U> struct PM_traits<U T::*> { using member_type = U; }; int main() { using T = PM_traits<decltype(&A::fun)>::member_type; // T es int() const& static_assert(std::is_function_v<T>); }
Véase también
|
verifica si un tipo puede ser invocado (como si fuera mediante
std::invoke
) con los tipos de argumentos dados
(plantilla de clase) |
|
|
(C++11)
|
verifica si un tipo es un tipo objeto
(plantilla de clase) |
|
(C++11)
|
verifica si un tipo es un tipo clase no-union
(plantilla de clase) |