Compatibilidad del compilador con rasgos de tipo (C++/CLI y C++/CX)

El compilador de Microsoft C++ admite rasgos de tipo para extensiones de C++/CLI y C++/CX, que indican diversas características de un tipo en tiempo de compilación.

Todos los runtimes

Comentarios

Los rasgos de tipo son especialmente útiles para los programadores que escriben las bibliotecas.

En la tabla siguiente se muestran los rasgos de tipo que admite el compilador. Todos los rasgos de tipo devuelven false si la condición especificada con el nombre de rasgo de tipo no se cumple.

(En la lista siguiente, los ejemplos de código solo se escriben en C++/CLI. Pero el rasgo de tipo correspondiente también se admite en C++/CX a menos que se indique lo contrario. El término "tipo de plataforma" hace referencia a tipos de Windows Runtime o a tipos de Common Language Runtime).

  • __has_assign(type)

    Devuelve true si el tipo de plataforma o nativo tiene un operador de asignación de copia.

    ref struct R {
    void operator=(R% r) {}
    };
    
    int main() {
    System::Console::WriteLine(__has_assign(R));
    }
    
  • __has_copy(type)

    Devuelve true si el tipo de plataforma o nativo tiene un constructor de copia.

    ref struct R {
    R(R% r) {}
    };
    
    int main() {
    System::Console::WriteLine(__has_copy(R));
    }
    
  • __has_finalizer(type)

    (No se admite en C++/CX). Devuelve true si el tipo CLR tiene un finalizador. Para más información, vea Destructores y finalizadores en Procedimiento: Definición y consumo de clases y estructuras (C++/CLI).

    using namespace System;
    ref struct R {
    ~R() {}
    protected:
    !R() {}
    };
    
    int main() {
    Console::WriteLine(__has_finalizer(R));
    }
    
  • __has_nothrow_assign(type)

    Devuelve true si un operador de asignación de copia tiene una especificación de excepción vacía.

    #include <stdio.h>
    struct S {
    void operator=(S& r) throw() {}
    };
    
    int main() {
    __has_nothrow_assign(S) == true ?
    printf("true\n") : printf("false\n");
    }
    
  • __has_nothrow_constructor(type)

    Devuelve true si el constructor predeterminado tiene una especificación de excepción vacía.

    #include <stdio.h>
    struct S {
    S() throw() {}
    };
    
    int main() {
    __has_nothrow_constructor(S) == true ?
    printf("true\n") : printf("false\n");
    }
    
  • __has_nothrow_copy(type)

    Devuelve true si el constructor de copia tiene una especificación de excepción vacía.

    #include <stdio.h>
    struct S {
    S(S& r) throw() {}
    };
    
    int main() {
    __has_nothrow_copy(S) == true ?
    printf("true\n") : printf("false\n");
    }
    
  • __has_trivial_assign(type)

    Devuelve true si el tipo tiene un operador trivial de asignaciones generado por el compilador.

    #include <stdio.h>
    struct S {};
    
    int main() {
    __has_trivial_assign(S) == true ?
    printf("true\n") : printf("false\n");
    }
    
  • __has_trivial_constructor(type)

    Devuelve true si el tipo tiene un constructor trivial generado por el compilador.

    #include <stdio.h>
    struct S {};
    
    int main() {
    __has_trivial_constructor(S) == true ?
    printf("true\n") : printf("false\n");
    }
    
  • __has_trivial_copy(type)

    Devuelve true si el tipo tiene un constructor trivial de copia generado por el compilador.

    #include <stdio.h>
    struct S {};
    
    int main() {
    __has_trivial_copy(S) == true ?
    printf("true\n") : printf("false\n");
    }
    
  • __has_trivial_destructor(type)

    Devuelve true si el tipo tiene un destructor trivial de generado por el compilador.

    // has_trivial_destructor.cpp
    #include <stdio.h>
    struct S {};
    
    int main() {
    __has_trivial_destructor(S) == true ?
    printf("true\n") : printf("false\n");
    }
    
  • __has_user_destructor(type)

    Devuelve true si el tipo de plataforma o nativo tiene un destructor declarado por el usuario.

    // has_user_destructor.cpp
    
    using namespace System;
    ref class R {
    ~R() {}
    };
    
    int main() {
    Console::WriteLine(__has_user_destructor(R));
    }
    
  • __has_virtual_destructor(type)

    Devuelve true si el tipo tiene un destructor virtual.

    __has_virtual_destructor también funciona en tipos de plataforma, y cualquier destructor definido por el usuario en un tipo de plataforma es un destructor virtual.

    // has_virtual_destructor.cpp
    #include <stdio.h>
    struct S {
    virtual ~S() {}
    };
    
    int main() {
    __has_virtual_destructor(S) == true ?
    printf("true\n") : printf("false\n");
    }
    
  • __is_abstract(type)

    Devuelve true si el tipo es un tipo abstracto. Para más información sobre los tipos abstractos nativos, consulte Clases abstractas.

    __is_abstract también funciona en los tipos de plataforma. Una interfaz con al menos un miembro es un tipo abstracto, como también lo es un tipo de referencia con al menos un miembro abstracto. Para más información sobre tipos de plataforma abstractos, consulte abstract.

    // is_abstract.cpp
    #include <stdio.h>
    struct S {
    virtual void Test() = 0;
    };
    
    int main() {
    __is_abstract(S) == true ?
    printf("true\n") : printf("false\n");
    }
    
  • __is_base_of( base , derived )

    Devuelve true si el primer tipo es una clase base del segundo tipo o si ambos tipos son iguales.

    __is_base_of también funciona en tipos de plataforma. Por ejemplo, devolverá true si el primer tipo es una clase de interfaz y el segundo tipo implementa la interfaz.

    // is_base_of.cpp
    #include <stdio.h>
    struct S {};
    struct T : public S {};
    
    int main() {
    __is_base_of(S, T) == true ?
    printf("true\n") : printf("false\n");
    
    __is_base_of(S, S) == true ?
    printf("true\n") : printf("false\n");
    }
    
  • __is_class(type)

    Devuelve true si el tipo es una clase o un struct nativos.

    #include <stdio.h>
    struct S {};
    
    int main() {
    __is_class(S) == true ?
    printf("true\n") : printf("false\n");
    }
    
  • __is_convertible_to( from , to )

    Devuelve true si el primer tipo se puede convertir en el segundo tipo.

    #include <stdio.h>
    struct S {};
    struct T : public S {};
    
    int main() {
    S * s = new S;
    T * t = new T;
    s = t;
    __is_convertible_to(T, S) == true ?
    printf("true\n") : printf("false\n");
    }
    
  • __is_delegate(type)

    Devuelve true si type es un delegado. Para más información, consulte delegado (C++/CLI y C++/CX).

    delegate void MyDel();
    int main() {
    System::Console::WriteLine(__is_delegate(MyDel));
    }
    
  • __is_empty(type)

    Devuelve true si el tipo no tiene ningún miembro de datos de instancia.

    #include <stdio.h>
    struct S {
    int Test() {}
    static int i;
    };
    int main() {
    __is_empty(S) == true ?
    printf("true\n") : printf("false\n");
    }
    
  • __is_enum(type)

    Devuelve true si el tipo es una enumeración nativa.

    // is_enum.cpp
    #include <stdio.h>
    enum E { a, b };
    
    struct S {
    enum E2 { c, d };
    };
    
    int main() {
    __is_enum(E) == true ?
    printf("true\n") : printf("false\n");
    
    __is_enum(S::E2) == true ?
    printf("true\n") : printf("false\n");
    }
    
  • __is_interface_class(type)

    Devuelve true si se pasa una interfaz de plataforma. Para más información, consulte interface class.

    // is_interface_class.cpp
    
    using namespace System;
    interface class I {};
    int main() {
    Console::WriteLine(__is_interface_class(I));
    }
    
  • __is_pod(type)

    Devuelve true si el tipo es una clase o unión sin constructor ni ningún miembro no estático privado o protegido, sin clases base y sin funciones virtuales. Vea el estándar de C++, secciones 8.5.1/1, 9/4 y 10 3.9 para más información sobre POD.

    __is_pod devuelve false en tipos fundamentales.

    #include <stdio.h>
    struct S {};
    
    int main() {
    __is_pod(S) == true ?
    printf("true\n") : printf("false\n");
    }
    
  • __is_polymorphic(type)

    Devuelve true si un tipo nativo tiene funciones virtuales.

    #include <stdio.h>
    struct S {
    virtual void Test(){}
    };
    
    int main() {
    __is_polymorphic(S) == true ?
    printf("true\n") : printf("false\n");
    }
    
  • __is_ref_array(type)

    Devuelve true si se pasa una matriz de plataforma. Para más información, consulte Matrices.

    using namespace System;
    int main() {
    array<int>^ x = gcnew array<int>(10);
    Console::WriteLine(__is_ref_array(array<int>));
    }
    
  • __is_ref_class(type)

    Devuelve true si se pasa una clase de referencia. Para más información sobre los tipos de referencia definidos por el usuario, consulte Clases y structs.

    using namespace System;
    ref class R {};
    int main() {
    Console::WriteLine(__is_ref_class(Buffer));
    Console::WriteLine(__is_ref_class(R));
    }
    
  • __is_sealed(type)

    Devuelve true si se pasa una tipo de plataforma o nativo marcado como sealed. Para más información, consulte sealed.

    ref class R sealed{};
    int main() {
    System::Console::WriteLine(__is_sealed(R));
    }
    
  • __is_simple_value_class(type)

    Devuelve true si se pasa un tipo de valor que no contiene referencias al montón de recolección de elementos no utilizados. Para más información sobre los tipos de valores definidos por el usuario, consulte Clases y structs.

    using namespace System;
    ref class R {};
    value struct V {};
    value struct V2 {
    R ^ r;   // not a simple value type
    };
    
    int main() {
    Console::WriteLine(__is_simple_value_class(V));
    Console::WriteLine(__is_simple_value_class(V2));
    }
    
  • __is_union(type)

    Devuelve true si un tipo es una unión.

    #include <stdio.h>
    union A {
    int i;
    float f;
    };
    
    int main() {
    __is_union(A) == true ?
    printf("true\n") : printf("false\n");
    }
    
  • __is_value_class(type)

    Devuelve true si se pasa un tipo de valor. Para más información sobre los tipos de valores definidos por el usuario, consulte Clases y structs.

    value struct V {};
    
    int main() {
    System::Console::WriteLine(__is_value_class(V));
    }
    

Windows en tiempo de ejecución

Comentarios

El rasgo de tipo __has_finalizer(type) no se admite porque esta plataforma no es compatible con los finalizadores.

Requisitos

Opción del compilador: /ZW

Common Language Runtime

Comentarios

(No hay ninguna observación específica de la plataforma para esta característica).

Requisitos

Opción del compilador: /clr

Ejemplos

Ejemplo

En el ejemplo de código siguiente se muestra cómo usar una plantilla de clase para exponer un rasgo de tipo de compilador para una compilación de /clr. Para más información, consulte Windows Runtime y plantillas administradas.

// compiler_type_traits.cpp
// compile with: /clr
using namespace System;

template <class T>
ref struct is_class {
   literal bool value = __is_ref_class(T);
};

ref class R {};

int main () {
   if (is_class<R>::value)
      Console::WriteLine("R is a ref class");
   else
      Console::WriteLine("R is not a ref class");
}
R is a ref class

Consulte también

Extensiones de componentes de .NET y UWP