可変引数の関数を作る

もくじ
https://tera1707.com/entry/2022/02/06/144447

やりたいこと

最近見たコードに「va_start」という、謎の関数?マクロ?が出てきた。

また、引数に「...」とか書いてある関数が出てきた。

どうもこれは、C++の引数を可変個取れる関数らしい。

使い方を知りたい。

実験プログラム

とりあえず、下記のコードを書いてみた。

可変個の引数をとる関数は、下記のようにつくる

  • 1個目の引数を、普通に書く(下記でいえば、char count)
  • その後ろに、「...」を書く
  • 関数の中で「va_list arglist;」を定義する
  • va_start()の
    • 引数の一個目に、👆のarglistを載せる
    • 引数の二個目に、可変の引数の前に書く引数を載せる(下記だと「count」)
  • 可変の引数を使いたいときに、「auto v = va_arg(arglist, <引数の型>);」を書く
  • その後、受ける可変引数の数だけ、「auto v = va_arg(arglist, <引数の型>);」を書く

※注意

実際に渡した引数の数を超えて「auto v = va_arg(arglist, <引数の型>);」をしても、vがNULLになったりはしてくれないので注意。(不定な値が取れてしまう)

#include <iostream>
#include <stdarg.h>//va_startに必要
#include <locale.h>//setlocaleに必要
#include <stdio.h>

void kahenchoHikisuu(char count, ...)
{
    va_list arglist;

    va_start(arglist, count); 

    auto v = va_arg(arglist, int);
    std::wcout << v << std::endl;

    auto v2 = va_arg(arglist, wchar_t*);
    std::wcout << v2 << std::endl;

    // 可変引数の数は、わからない。
    // なので、printfのように、第一引数の文字列の中にある%の数で数える、などの工夫が必要。

    va_end(arglist);
}

int main()
{
    setlocale(LC_ALL, "Japanese");

    kahenchoHikisuu(1, 2, L"あいうえお");
}

特記事項は、コメントにも書いたが、

  • 可変引数の数は、わからない。
  • なので、printfのように、第一引数の文字列の中にある%の数で数える、とか、引数の数を第一引数で受け取る、などの工夫が必要。

参考

C言語の可変長引数の関数の作り方

https://qiita.com/subaruf/items/657c67a1809515589a7c