可変個の引数とnon-POD型
まず、可変個の引数を取る関数の書き方のおさらい。
こんな感じで、num個のuint型を足し合わせる関数が定義できる。
#include
uint sum(uint num, ...)
{
uint retval = 0;
va_list ap;
va_start(ap, num);for(uint i= 0; i < num; i++)
{
retval += va_arg(ap, uint);
}va_end(ap);
return retval;
}
しかし、va_argで読み出せる型はPOD型(PODはPlain Old Dataの略)に限られる。コンストラクタやデコンストラクタがユーザー定義だったりすると、non-POD型になってしまう(PODとnon-PODの正確な定義はよくわからん)。そういった型を引数に取りたい場合は、ポインタでデータを渡してやれば良い。
これはダメだけど、
#include
cmtrx tensor_prod(uint num, ...)
{
if(!num){return cmtrx();}va_list ap;
va_start(ap, num);cmtrx output = va_arg(ap, const cmtrx &);
for(uint i = 1; i < num; i++)
{
output = tensor_prod(output, va_arg(ap, const cmtrx &));
}va_end(ap);
return output;
}
これならOK。ちなみに上記のcmtrx型はboostの複素行列で、
#include
cmtrx tensor_prod(uint num, ...)
{
if(!num){return cmtrx();}va_list ap;
va_start(ap, num);cmtrx output = *va_arg(ap, const cmtrx *);
for(uint i = 1; i < num; i++)
{
output = tensor_prod(output, *va_arg(ap, const cmtrx *));
}va_end(ap);
return output;
}
こんな感じに定義したものです。
#include
typedef std::complexcmplx;
typedef boost::numeric::ublas::matrixcmtrx;