可変個の引数とnon-POD型

まず、可変個の引数を取る関数の書き方のおさらい。


#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;
}

こんな感じで、num個のuint型を足し合わせる関数が定義できる。
しかし、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;
}

これはダメだけど、

#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
typedef std::complex cmplx;
typedef boost::numeric::ublas::matrix cmtrx;
こんな感じに定義したものです。

SSHのポートフォワードとmathematicaのネットワークライセンス

ネットワーク構成

  • 認証サーバ(opteron) 192.168.0.100
  • sshサーバ(tadpole) 192.168.0.1 192.168.1.1
  • クライアント(praw) 192.168.1.100

praw上で以下のコマンドを実行し、16286番ポートをフォワーディングする。


ssh -N -f -L 16286:opteron:16286 tadpole
prawの/etc/hostsを以下のように書き換えて、opteronの参照先を自分に。

127.0.0.1 localhost.localdomain localhost opteron
mathpassファイル(/opt/Wolfram/Mathematica/6.0/Configuration/Licensing/mathpass等)を以下の用に記す。

!opteron
これでOK。
ポート番号さえ分かれば、他のソフトウェアでも同じ方法が使えるはず。
2010/08/26追記。/etc/hostsを修正する必要は無い。mathpassファイルに
!localhost
と書けばよい。