/Zc:enumTypes (列挙型の推論を有効にする)

/Zc:enumTypesコンパイラ オプションを使用すると、基になる型と列挙子の型推論に準拠する enum C++ が有効になります。

構文

/Zc:enumTypes[-]

解説

コンパイラ オプションは /Zc:enumTypes 、列挙型の基本型と列挙子の型を推論するための標準 C++ 準拠動作を実装します。

この /Zc:enumTypes オプションは、Visual Studio 2022 バージョン 17.4 の新機能です。 このオプションは既定ではオフになっており /permissive-、. このオプションを明示的に無効にするには、次を使用 /Zc:enumTypes-します。

有効にした場合、/Zc:enumTypes オプションはソースとバイナリの破壊的変更になる可能性があります。 一部の列挙型は、準拠オプションが有効になっているとサイズが /Zc:enumTypes 変更されます。 特定の Windows SDK ヘッダーには、このような列挙型の定義が含まれています。

C++ 標準では、列挙型の基になる型が、その中で宣言されているすべての列挙子を保持するのに十分な大きさである必要があります。 十分に大きな列挙子は、enum の基となる型を unsigned intlong long、または unsigned long long に設定できます。 以前は、このような列挙型には、列挙子の int 値に関係なく、常に基になる型が Microsoft コンパイラに含まれていました。

また、C++ 標準では、固定の基になる型を持たない列挙定義内で、列挙子の型が初期化子によって決定されるように指定します。 または、初期化子のない列挙子の場合は、(オーバーフローを考慮して) 直前の列挙子の型によって決定されます。 以前は、このような列挙子には、基となる型のプレースホルダー (通常は int) と共に、列挙型の推定型が常に指定されていました。

Visual Studio 2022 バージョン 17.4 より前のバージョンの Visual Studio に含まれる C++ コンパイラでは、固定の基本データ型がない、スコープを持たない列挙型の基となる型が正しく判断されませんでした。 コンパイラも、列挙子の型を正しくモデル化しませんでした。 列挙型の右中かっこの前に固定の基となる型がない場合、列挙型で不適切な型が想定される可能性がありました。 コンパイラ /Zc:enumTypesでは、標準動作が正しく実装されています。

例: 固定型のないスコープ enum 外の基になる型

enum Unsigned
{
    A = 0xFFFFFFFF // Value 'A' does not fit in 'int'.
};

// Previously, this static_assert failed. It passes with /Zc:enumTypes.
static_assert(std::is_same_v<std::underlying_type_t<Unsigned>, unsigned int>);

template <typename T>
void f(T x)
{
}

int main()
{
    // Previously called f<int>, now calls f<unsigned int>.
    f(+A);
}

// Previously, this enum would have an underlying type of `int`,
// but Standard C++ requires this to have a 64-bit underlying type.
// The /Zc:enumTypes option changes the size of this enum from 4 to 8,
// which could impact binary compatibility with code compiled with an
// earlier compiler version, or without the switch.
enum Changed
{
    X = -1,
    Y = 0xFFFFFFFF
};

例: 基になる型が enum 固定されていない定義内の列挙子

enum Enum {
    A = 'A',
    B = sizeof(A)
};

static_assert(B == 1); // previously failed, now succeeds under /Zc:enumTypes

この例では、列挙型の右中かっこの前にある列挙子 A は型 char である必要があります。そのため、Bsizeof(char) を使って初期化する必要があります。 /Zc:enumTypes の修正前は、A は列挙型 Enum であり、推論される基となる型は int でした。Bsizeof(Enum) (つまり 4) を使って初期化されていました。

このコンパイラ オプションを Visual Studio で使用するには

  1. プロジェクトの [プロパティ ページ] ダイアログ ボックスを開きます。 詳細については、Visual Studio での C++ コンパイラとビルド プロパティの設定に関する記事を参照してください。

  2. [構成プロパティ]>[C/C++]>[コマンド ライン] プロパティ ページを選択します。

  3. [その他のオプション] で、追加/Zc:enumTypesまたは /Zc:enumTypes-. [OK] または [適用] を選択して、変更内容を保存します。

関連項目

/Zc (準拠)
/std (言語の標準バージョンの指定)