Suporte do compilador para traços de tipo (C++/CLI e C++/CX)

O compilador de C++ da Microsoft é compatível com traços de tipo para extensões de C++/CLI e C++/CX, que indicam várias características de um tipo em tempo de compilação.

Todos os Runtimes

Comentários

Os traços de tipo são especialmente úteis para programadores que escrevem bibliotecas.

A lista a seguir contém os traços de tipo compatíveis com o compilador. Todas as características de tipo retornam false se a condição especificada pelo nome da característica de tipo não for encontrada.

(Na lista a seguir, os exemplos de código são gravados apenas em C++/CLI. Porém, a característica de tipo correspondente também é compatível no C++/CX, a menos que indicado de outra forma. O termo "tipo de plataforma" refere-se tanto aos tipos do Windows Runtime quanto aos tipos do Common Language Runtime.)

  • __has_assign(tipo)

    Retorna true se a plataforma ou tipo nativo tiver um operador de atribuição de cópia.

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

    Retorna true se a plataforma ou tipo nativo tiver um construtor de cópia.

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

    (Não compatível em C++/CX.) Retorna ao true se o tipo CLR tiver um finalizador. Confira Destruidores e finalizadores em Como: definir e consumir classes e structs (C++/CLI) para saber mais.

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

    Retorna true se um operador de atribuição de cópia tiver uma especificação de exceção vazia.

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

    Retorna true se o construtor padrão tiver uma especificação de exceção vazia.

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

    Retorna true se o construtor de cópia tiver uma especificação de exceção vazia.

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

    Retorna true se o tipo tiver um operador de atribuição trivial gerado pelo compilador.

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

    Retorna true se o tipo tiver um construtor trivial gerado pelo compilador.

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

    Retorna true se o tipo tiver um construtor de cópia trivial gerado pelo compilador.

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

    Retorna true se o tipo tiver um destruidor trivial gerado pelo 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(tipo)

    Retorna true se a plataforma ou tipo nativo tiver um destruidor declarado pelo usuário.

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

    Retorna true se o tipo tiver um destruidor virtual.

    __has_virtual_destructor também funciona em tipos de plataforma, e qualquer destruidor definido pelo usuário em um tipo de plataforma é um destruidor 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(tipo)

    Retorna true se o tipo for um tipo abstrato. Saiba mais sobre tipos abstratos nativos em Classes abstratas.

    __is_abstract também funciona para tipos de plataforma. Uma interface com pelo menos um membro é um tipo abstrato, assim como um tipo de referência com pelo menos um membro abstrato. Saiba mais sobre tipos de plataforma abstratos em 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 )

    Retorna true se o primeiro tipo for uma classe base do segundo tipo ou se ambos os tipos forem iguais.

    __is_base_of também funciona em tipos de plataforma. Por exemplo, retornará true se o primeiro tipo for uma classe de interface e o segundo tipo implementar a 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(tipo)

    Retorna true se o tipo for uma classe nativa ou struct.

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

    Retorna true se o primeiro tipo puder ser convertido no 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(tipo)

    Retorna true se type for um delegado. Para obter mais informações, confira delegado (C++/CLI e C++/CX).

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

    Retorna true se o tipo não tiver membros de dados de instância.

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

    Retorna true se o tipo for uma enumeração 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(tipo)

    Retorna true se uma interface de plataforma for passada. Saiba mais em classe de interface.

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

    Retorna true se o tipo for uma classe ou união sem construtor ou membros não estáticos privados ou protegidos, sem classes base nem funções virtuais. Confira o C++ padrão, seções 8.5.1/1, 9/4 e 3.9/10 para saber mais sobre PODs.

    __is_pod retornará false em tipos fundamentais.

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

    Retorna true se um tipo nativo tiver funções virtuais.

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

    Retorna true se uma matriz de plataforma for passada. Saiba mais em Matrizes.

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

    Retorna true se uma classe de referência for passada. Saiba mais sobre tipos de referência definidos pelo usuário em Classes e Structs.

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

    Retorna true se uma plataforma ou tipo nativo forem passados marcados como selados. Saiba mais em selado.

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

    Retorna true se um tipo de valor que não contém referências for passado para o heap coletado como lixo. Saiba mais sobre tipos de valor definidos pelo usuário em Classes e 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(tipo)

    Retorna true se um tipo for uma união.

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

    Retorna true se um tipo de valor for passado. Saiba mais sobre tipos de valor definidos pelo usuário em Classes e structs.

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

Windows Runtime

Comentários

O traço __has_finalizer(tipo) não é compatível porque esta plataforma não é compatível com finalizadores.

Requisitos

Opção do compilador: /ZW

Common Language Runtime

Comentários

(Não há comentários específicos da plataforma para esse recurso.)

Requisitos

Opção do compilador: /clr

Exemplos

Exemplo

O exemplo de código a seguir mostra como usar um modelo de classe para expor um traço de tipo de compilador para uma compilação /clr. Saiba mais em Windows Runtime e modelos gerenciados.

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

Confira também

Extensões de componentes para .NET e UWP