Поддержка признаков типов компилятором (C++/CLI и C++/CX)

Компилятор C++ Microsoft поддерживает признаки типов для расширений C++/CLI и C++/CX, которые указывают различные характеристики типов во время компиляции.

Все среды выполнения

Замечания

Признаки типов особенно важны для программистов, создающих библиотеки.

В следующем списке перечислены признаки типов, поддерживаемые компилятором. Все признаки типа возвращаются false , если условие, указанное именем признака типа, не выполняется.

(В следующем списке примеры кода записываются только в C++/CLI. Но соответствующий признак типа также поддерживается в C++/CX, если не указано иное. Термин "тип платформы" относится либо к типам среда выполнения Windows, либо типам среды CLR.)

  • __has_assign(type)

    Возвращает, true имеет ли платформа или собственный тип оператор назначения копирования.

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

    Возвращает, true имеет ли платформа или собственный тип конструктор копирования.

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

    (Не поддерживается в C++/CX.) Возвращает значение true , если тип СРЕДЫ CLR имеет метод завершения. Дополнительные сведения см. в разделе "Деструкторы и методы завершения: определение и использование классов и структур (C++/CLI).

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

    Возвращает, true если оператор назначения копирования имеет пустую спецификацию исключения.

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

    Возвращает, true если конструктор по умолчанию имеет пустую спецификацию исключения.

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

    Возвращает, true если конструктор копирования имеет пустую спецификацию исключения.

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

    Возвращает, true если тип имеет тривиальный, созданный компилятором оператор назначения.

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

    Возвращает, true если тип имеет тривиальный конструктор, созданный компилятором.

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

    Возвращает, true если тип имеет тривиальный конструктор копирования, созданный компилятором.

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

    Возвращает, true если тип имеет тривиальный деструктор, созданный компилятором.

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

    Возвращает, true если платформа или собственный тип имеет деструктор, объявленный пользователем.

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

    Возвращает, true если тип имеет виртуальный деструктор.

    Признак __has_virtual_destructor также работает с типами платформ, и любой определенный пользователем деструктор в типе платформы является виртуальным деструктором.

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

    Возвращает, true является ли тип абстрактным типом. Дополнительные сведения о собственных абстрактных типах см. в статье Abstract Classes (Абстрактные типы (C++)).

    Признак __is_abstract также работает с типами платформ. Интерфейс хотя бы с одним членом является абстрактным типом, как и ссылочный тип по крайней мере с одним абстрактным членом. Дополнительные сведения об абстрактных типах платформ см. в статье abstract (C++/CLI and C++/CX) (abstract (C++/CLI и C++/CX)).

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

    Возвращает, true является ли первый тип базовым классом второго типа, или если оба типа одинаковы.

    Признак __is_base_of также работает с типами платформ. Например, он возвращаетсяtrue, если первый тип является классом интерфейса, а второй тип реализует интерфейс.

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

    Возвращает, true является ли тип собственным классом или структурой.

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

    Возвращает, true можно ли преобразовать первый тип во второй тип.

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

    Возвращается true , если type является делегатом. Дополнительные сведения см. в статье delegate (C++/CLI and C++/CX).

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

    Возвращает, true если тип не содержит элементов данных экземпляра.

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

    Возвращает, true является ли тип собственным перечислением.

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

    Возвращается true , если передан интерфейс платформы. Дополнительные сведения см. в статье interface class.

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

    Возвращает значение true , если тип является классом или объединением без конструктора или закрытого или защищенного нестатического элемента, базовых классов и виртуальных функций. Дополнительные сведения о POD см. в разделах 8.5.1/1, 9/4 и 3.9/10 стандарта C++.

    Для фундаментальных типов признак __is_pod возвращает значение false.

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

    Возвращает, true если собственный тип имеет виртуальные функции.

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

    Возвращается true , если передан массив платформы. Дополнительные сведения см. в статье Arrays (C++/CLI and C++/CX) (Массивы (C++/CLI и C++/CX)).

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

    Возвращается true , если передан ссылочный класс. Дополнительные сведения об определяемых пользователем ссылочных типах см. в статье ref class and ref struct (C++/CLI and C++/CX) (ref class и ref struct (C++/CLI и C++/CX)).

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

    Возвращается true , если передана платформа или собственный тип, помеченный запечатанным. Дополнительные сведения см. в статье sealed (C++/CLI and C++/CX).

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

    Возвращается true , если передан тип значения, который не содержит ссылок на сборку мусора. Дополнительные сведения об определяемых пользователем типах значений см. в статье ref class and ref struct (C++/CLI and C++/CX) (ref class и ref struct (C++/CLI и C++/CX)).

    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)

    Возвращает, true является ли тип объединением.

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

    Возвращается true , если передан тип значения. Дополнительные сведения об определяемых пользователем типах значений см. в статье ref class and ref struct (C++/CLI and C++/CX) (ref class и ref struct (C++/CLI и C++/CX)).

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

Среда выполнения Windows

Замечания

Признак типа __has_finalizer(type) не поддерживается, поскольку эта платформа не поддерживает методы завершения.

Требования

Параметр компилятора: /ZW

Среда CLR

Замечания

(Отсутствуют комментарии для данной возможности в рамках этой платформы).

Требования

Параметр компилятора: /clr

Примеры

Пример

В следующем примере кода показано использование шаблона класса для предоставления признака типа компилятора при компиляции /clr. Дополнительные сведения см. в статье Windows Runtime and Managed Templates (C++/CLI and C++/CX) (Среда выполнения Windows и управляемые шаблоны (C++/CLI и C++/CX)).

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

См. также

Расширения компонентов для .NET и UWP