• Class / Function / Type

      std::
    • Header file

      <>
    • Other / All

    最終更新日時(UTC):
    が更新

    履歴 編集

    可変引数が空でない場合のトークン置換 [P0306R4]

    このページは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");       // printf("[debug] hello\n"); に展開される
      DEBUG_LOG("value:%d", 3); // printf("[debug] value:%d\n", 3); に展開される
    }
    

    出力

    [debug] hello
    [debug] value:3
    

    関連項目

    参照