Members/chinone/覚書

C++ tips

inner_product, binary_function

template <class T>
class demod : std::public binary_function<T,unsigned char,T>
{
 public:
  T operator()(T x,unsigned char y)
  {
    return (T) (x*pow(-1,static_cast<int>(y))) ;
  }
};
double demod_avg = std::inner_product( demod.begin(), demod.end(),
                                       hz.begin(), 0.0,
                                       std::plus<double>(),
                                       demod<double>()
                                     );

数値ファイルの読込

boostを活用:

std::string filename = argv[1] ;
std::ifstream fin( filename.c_str(), std::ios::in) ;

std::vector<double> mjd, tp, demod ;

std::string buf ;
std::vector<std::string> line ;
while( fin && getline(fin,buf) ){
  boost::algorithm::split( line, buf, boost::is_space(), boost::algorithm::token_compress_on) ;
  assert( line.size()==ncols ) ;

  mjd.push_back( boost::lexical_cast<double>(line[imjd]) ) ;
  tp.push_back( boost::lexical_cast<double>(line[itp]) ) ;
  demod.push_back( boost::lexical_cast<double>(line[idemod]) ) ;
}
fin.close() ;

uintの定義

#include <sys/types.h>

NaNを返す

#include <limits>

してから、

std::numeric_limits<double>::quiet_NaN()

で利用。

「_」で終わる変数

class hoge
{
public:
protected:
  virtual uint nrows() const {return nrows_;}
  virtual TCanvas* canvas() const {return canvas_;}
private:
  uint nrows_ ;
  TCanvas *canvas_ ;
};

フィールド名の先頭か末尾にアンダースコアを含める。 このアプローチの利点はフィールド名を扱っていることが一目で分かるため、 パラメータやローカル変数によって隠蔽されることを防ぐことができる。 尚、C言語では、アンダーバーで始まる名前は標準または処理系のマクロや(外部リンケージを持つ)変数名・関数名のために予約されている。

マニピュレータ

#include <iomanip>
 cout << setfill(' ') << setprecision(3) << fixed ;
 for( int order=6; order<=in_order; order++){
   int nside = 1<<order ;
   int npix = 12*nside*nside ;
   cout << setw(3)
        << order << " " << setw(12)
        << npix << " " << setw(9)
        << test.get_calc_time( order, 2) << endl ;

マニピュレータには

  1. 設定内容が持続するもの
  2. 設定内容が一回だけ有効なもの(ワンショット)

がある。ワンショットにはsetw(int n)が該当する。

setprecision(int n)
精度桁数をn桁にする。
fixed
固定形式にする。上の例だと小数部が3桁に固定される。

正直、iomanipを使うくらいだったら、printf系関数を使った方が便利。 またはboost::formatを使うべき。

配列

C++でmallocはあまり使わない。

一次元

  • malloc
     double *V0 ;
     V0 = (double*)malloc(sizeof(double)*y) ;
     ............
     free(V0) ;
  • new
     double *V1 ;
     V1 = new double [y] ;
     ............
     delete [] V1 ;
  • vector
     vector<double> V2 ;
     V2.resize(y) ;
     ....
     V2.clear() ;

二次元

  • malloc
     double **v0 ;
     v0 = (double**)malloc(sizeof(double*)*x) ;
     for( int i=0; i<x; i++)
       v0[i] = (double*)malloc(sizeof(double)*y) ;
     ...........
     for( int i=0; i<x; i++)
       free(v0[i]) ;
     free(v0) ;
  • new
     double **v1 ;
     v1 = new double* [x] ;
     for( int i=0; i<x; i++)
       v1[i] = new double [y] ;
     ............
     for( int i=0; i<x; i++)
       delete [] v1[i] ;
     delete [] v1 ;
  • vector
    vector<vector<double> > v1 ;
    v1.resize(x) ;
    for( int i=0; i<x; i++)
       v1.resize(y) ;