ぼく用あれこれまとめ

可変長引数

最終更新:

bokuyo

- view
管理者のみ編集可

可変長引数

  • いま読み返すと、この記事の適当さ加減がやばい。

Cでの実装

#include <iostream>
#include <stdarg.h>

int unco(int renton, ...)
{
	va_list list;				//va_list型は<stdarg.h>で定義されてる
	va_start(list, renton);			//可変長引数の要素を扱い始めるためのva_start()マクロ
	int eureka = va_arg(list, int);		//リストの次の要素を取り出す。popとかdequeueみたいな感じ。
	while(eureka != 0)
	{
		renton += eureka;
		eureka = va_arg(list, int);
	}
	va_end(list);				//可変長引数の要素を扱い終わるためのva_endマクロ

	return renton;
}

int main()
{
	std::cout << unco(1, 5, 6, 0, 7, 7, 8, -4, 9, 156) << std::endl;
	return 0;
}
  • なんか上手く使った気がしないけど…。1+5+6を足して、0を引数に取るとループを抜ける。
  • 0を引数に取らないと無限ループしかねないソース。
  • マクロの中身を見てみたけど吐き気したからもう当分見る気ない。
  • ちなみにC++だと<cstdarg>をインクルードすればおっけー。

va_start(), va_arg(), va_end()マクロの中身をC++っぽく置き換えると

template<typename T>
void vaStart(va_list& ap, T& v)
{
	ap = (va_list)(&reinterpret_cast<const char &>(v)) + ((sizeof(v) + sizeof(int) - 1) & ~(sizeof(int) - 1));
}

template<typename T>
T vaArg(va_list& ap)		//使い方は vaArg<int>(list)みたいな。
{
	return ( *(T *)((ap += ((sizeof(T) + sizeof(int) - 1) & ~(sizeof(int) - 1))) - ((sizeof(T) + sizeof(int) - 1) & ~(sizeof(int) - 1))) );
}

void vaEnd(va_list& ap)
{
	ap = (va_list)0;
}
  • VC++2010の環境だとこんな感じ。そのままマクロを置き換えただけだけど…。
  • CにはC++みたくジェネリックプログラミングができないから仕方なしにマクロで書いてる部分もあるだろうと…。
    • マクロを書き直したからってそれがC++に通用するとは思えないから
    • このCライクな<stdarg.h>の可変長引数を使うのなら、マクロのままでいいかなーって思う。
    • そもそもC++だったらもっとかっこいい可変長引数をとる関数がかける…はず。きっとね。
  • やってることはリスト操作。
  • もし注目するなら、「reinterpret_cast」かな。あんまり見かけないからこの際知っとくのもいいかなって。
記事メニュー
目安箱バナー