最終更新日時: 2026年03月02日 21時08分56秒 (JST)
suomesta が更新

履歴 編集

# 可変引数が空でない場合のトークン置換 [P0306R4](C++20)

このページはC++20に採用された言語機能の変更を解説しています。

のちのC++規格でさらに変更される場合があるため関連項目を参照してください。

## 概要

新たなプリプロセスマクロ`__VA_OPT__`を追加する。このマクロは、マクロのパラメータとして受け取った可変引数が空でない場合に置換するトークンを指定する機能を持つ。

    #define F(X, ...) f(10, X __VA_OPT__(,) __VA_ARGS__)

    F(3);               // f(10, 3); に置換される
    F(3, "Hello", 'A'); // f(10, 3, "Hello", 'A'); に置換される

可変引数のために単に`__VA_ARGS__`を使用すると、可変引数が空だった場合に、カンマが余ってしまい、「`f(10, 3, );`」のように展開されて構文エラーとなる。`__VA_OPT__`マクロはその問題を回避するために使用できる。

`__VA_OPT__`マクロは引数として、可変引数が空でなかった場合に置換するトークンをとる。関数呼び出しのためのカンマを例として挙げたが、この引数には任意のトークンを指定できる。たとえば、リスト初期化の構文や、`__VA_ARGS__`をトークンに含めることもできる：

    #define SDEF(sname, ...) S sname __VA_OPT__(= { __VA_ARGS__ })

    SDEF(foo);          // S foo; に展開される
    SDEF(bar, 1, 2, 3); // S bar = {1, 2, 3}; に展開される

このマクロは、同じ仕様でC言語にも提案されている。「WG14 N2034 Comma omission and comma deletion」を参照。

## 例

    #include <cstdio>

    #define DEBUG_LOG(msg, ...) std::printf("[debug] " msg "\n" __VA_OPT__(,) __VA_ARGS__)

    int main()
    {
      DEBUG_LOG("hello");       // std::printf("[debug] hello\n"); に展開される
      DEBUG_LOG("value:%d", 3); // std::printf("[debug] value:%d\n", 3); に展開される
    }

### 出力

    [debug] hello
    [debug] value:3

## 関連項目

- C++11 可変引数マクロ

## 参照

- P0306R4 Comma omission and comma deletion