std::is_function
| Definido en el archivo de 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 el operador operator() sobrecargado y punteros a funciones no cuentan como 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.
El comportamiento de un programa que añade especializaciones para is_function o is_function_v (desde C++17) no está definido.
Parámetros de plantilla
| T | - | Un tipo a comprobar. |
Plantilla de variable auxiliar
<tbody> </tbody> template< class T > inline constexpr bool is_function_v = is_function<T>::value; |
(desde C++17) | |
Heredado de std::integral_constant
Constantes miembro
value [estático] |
true si T es un tipo función, de lo contrario false. (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 maneras mucho más simples. Las implementaciones similares a la siguiente se usan 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 debajo es para propósitos pedagógicos, ya que exhibe toda la gama de los distintos tipos de tipos función.
Posible implementación
// plantilla primaria
template<class>
struct is_function : std::false_type { };
// especialización para tipos regulares
template<class Ret, class... Args>
struct is_function<Ret(Args...)> : std::true_type {};
// especialización para funciones variádicas, tales como std::printf
template<class Ret, class... Args>
struct is_function<Ret(Args......)> : std::true_type {};
// especialización para tipos 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 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 {};
// especialización para las versiones noexcept de todas las dadas arriba
// (C++17 y posterior)
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 <iostream>
#include <type_traits>
struct A {
int fun() const&;
};
template<typename>
struct PM_traits {};
template<class T, class U>
struct PM_traits<U T::*> {
using member_type = U;
};
int f();
int main()
{
std::cout << std::boolalpha;
std::cout << std::is_function<A>::value << '\n';
std::cout << std::is_function<int(int)>::value << '\n';
std::cout << std::is_function<decltype(f)>::value << '\n';
std::cout << std::is_function<int>::value << '\n';
using T = PM_traits<decltype(&A::fun)>::member_type; // T es int() const&
std::cout << std::is_function<T>::value << '\n';
}
Salida:
false
true
true
false
true
Véase también
| Comprueba si un tipo puede invocarse (como si lo fuera por std::invoke) con el número de argumentos dado. (plantilla de clase) | |
(C++11) |
Comprueba si un tipo es un tipo objeto (plantilla de clase) |
(C++11) |
Comprueba si un tipo es un tipo clase (pero no un tipo unión). (plantilla de clase) |