Prise en charge du compilateur pour les traits de type (C++/CLI et C++/CX)

Le compilateur Microsoft C++ prend en charge les traits de type pour C++/CLI et les extensions C++/CX. Ils indiquent diverses caractéristiques d’un type au moment de la compilation.

Tous les runtimes

Notes

Les traits de type s'avèrent particulièrement utiles pour les programmeurs qui écrivent des bibliothèques.

La liste suivante répertorie les traits de type pris en charge par le compilateur. Toutes les caractéristiques de type retournent false si la condition spécifiée par le nom de la caractéristique de type n’est pas remplie.

(Dans la liste suivante, les exemples de code sont écrits uniquement en C++/CLI. Toutefois, la caractéristique de type correspondante est également prise en charge dans C++/CX, sauf indication contraire. Le terme « type de plateforme » fait référence aux types Windows Runtime ou aux types Common Language Runtime.)

  • __has_assign(type)

    Retourne true si la plateforme ou le type natif a un opérateur d’affectation de copie.

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

    Retourne true si la plateforme ou le type natif possède un constructeur de copie.

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

    (Non pris en charge dans C++/CX.) Retourne true si le type CLR a un finaliseur. Pour plus d’informations, consultez Les destructeurs et finaliseurs dans How to : Define and consume classes and structs (C++/CLI).

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

    Retourne true si un opérateur d’affectation de copie a une spécification d’exception vide.

    #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)

    Retourne true si le constructeur par défaut a une spécification d’exception vide.

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

    Retourne true si le constructeur de copie a une spécification d’exception vide.

    #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)

    Retourne true si le type a un opérateur d’affectation généré par le compilateur trivial.

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

    Retourne true si le type a un constructeur généré par le compilateur trivial.

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

    Retourne true si le type a un constructeur de copie généré par le compilateur trivial.

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

    Retourne true si le type a un destructeur généré par le compilateur trivial.

    // 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)

    Retourne true si la plateforme ou le type natif possède un destructeur déclaré par l’utilisateur.

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

    Retourne true si le type a un destructeur virtuel.

    __has_virtual_destructor fonctionne également sur les types de plateforme et tout destructeur défini par l'utilisateur dans un type de plateforme est un destructeur virtuel.

    // 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)

    Retourne true si le type est un type abstrait. Pour plus d’informations sur les types abstract natifs, consultez Classes abstract.

    __is_abstract fonctionne également pour les types de plateforme. Une interface avec au moins un membre est un type abstrait, à l'instar d'un type référence avec au moins un membre abstrait. Pour plus d’informations sur les types de plateforme abstraits, consultez 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 )

    Retourne true si le premier type est une classe de base du deuxième type, ou si les deux types sont identiques.

    __is_base_of fonctionne également sur les types de plateforme. Par exemple, elle retourne true si le premier type est une classe d’interface et que le deuxième type implémente l’interface.

    // 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)

    Retourne true si le type est une classe ou un struct natif.

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

    Retourne true si le premier type peut être converti en deuxième type.

    #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)

    Retourne true s’il s’agit type d’un délégué. Pour plus d’informations, consultez délégué (C++/CLI et C++/CX).

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

    Retourne true si le type n’a pas de membres de données d’instance.

    #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)

    Retourne true si le type est une énumération native.

    // 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)

    Retourne true si une interface de plateforme a été passée. Pour plus d’informations, consultez classe d’interface.

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

    Retourne true si le type est une classe ou une union sans constructeur ni membre privé ou non statique protégé, aucune classe de base et aucune fonction virtuelle. Consultez la norme C++, sections 8.5.1/1, 9/4 et 3.9/10 pour plus d'informations sur les POD.

    __is_pod retourne la valeur false sur les types fondamentaux.

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

    Retourne true si un type natif a des fonctions virtuelles.

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

    Retourne true si un tableau de plateforme a été passé. Pour plus d’informations, consultez Tableaux.

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

    Retourne true si une classe de référence a été passée. Pour plus d’informations sur les types référence définis par l’utilisateur, consultez Classes et structs.

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

    Retourne true si une plateforme ou un type natif est marqué comme scellé. Pour plus d’informations, consultez sealed.

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

    Retourne true si un type valeur qui ne contient aucune référence au tas collecté par le garbage-collected. Pour plus d’informations sur les types valeur définis par l’utilisateur, consultez Classes et 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)

    Retourne true si un type est une union.

    #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)

    Retourne true si un type valeur est passé. Pour plus d’informations sur les types valeur définis par l’utilisateur, consultez Classes et structs.

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

Windows Runtime

Notes

Le trait de type __has_finalizer(type) n’est pas pris en charge car cette plateforme ne prend pas en charge les finaliseurs.

Spécifications

Option du compilateur : /ZW

Common Language Runtime

Notes

(Il n’existe aucune note spécifique à la plateforme pour cette fonctionnalité.)

Spécifications

Option du compilateur : /clr

Exemples

Exemple

L'exemple de code suivant montre comment utiliser un modèle de classe pour exposer un trait de type de compilateur pour une compilation /clr. Pour plus d’informations, consultez Windows Runtime et modèles managés.

// 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

Voir aussi

Extensions de composants pour .NET et UWP