次の方法で共有


/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 (言語の標準バージョンの指定)