最終更新日時:
が更新

履歴 編集

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

概要

新たなプリプロセスマクロ__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

関連項目

参照