statifier

動的ライブラリをつかっているが実行時間が長く、途中でソースを変更したいけど、
今走っているのはそのままにしたい。
さらに、動的ライブラリではなく静的ライブラリを作る方法がよくわからん。
こんなことは滅多に起こらないと思うが、Geant4+rootでやっていると、
動的ライブラリしか生成されないのでちょっと困った。
そこで動的ライブラリから静的ライブラリを生成するコマンドがあるみたい。
それが表題のstatifier。

とおもってできたバイナリ実行したら即落ちしたwww

*+演算子!?

一瞬びびった。 たとえば、
double x = 100;
std::cout << x*+x << std::endl;
これは一瞬'*'か'+'かわからなくなるが、実際には、
std::cout << x*(+x) << std::endl;
こう解釈されるのでコンパイルが通ってしまう(手元のgccでは)。
エラー吐いてほしいな..

デマングル

typeinfo::name()をつかったときに名前が読みにくい。
これを綺麗にするのがデマングルというらしい。
http://0xcc.net/blog/archives/000095.html

double x=x

これをfor文やwhile文の中に書くとgccではなぜかこれがコンパイルを通ってしまう。 えええええええ。

gdb

参考: http://d.hatena.ne.jp/Sixeight/20081112/1226477394
$ ulimit -c unlimited
$ ulimit -c
unlimited

./main
seg (core dump)

gdb main core.xxx
(gdb) 

# valgrind --tool=memcheck --leak-check=yes ./test



cのabsとc++のabs

c++ではテンプレートにより?absでdoubleもintも扱える。
だけど、absはabsでもstd::absである。うへ。
ふつうにabsとだけ書くとintのabsが呼ばれる。はまったー。

c++の価値

引用 http://www.kab-studio.biz/Programing/Codian/STL/05.html
さて、 std::fill() の例は「意味なくない?」と思う方も多いでしょう。
前回使用した std::vector::assign() が同じ機能を持っているからです。
でもそれは違うのです。操作には std::vector::assign() などのメンバ関数は極力使用せず、
アルゴリズムを使用するべきです。 std::fill() と std::find() を同時に使用することで、
コードのスタイルを統一でき、可読性を高めます。
また、 std::vector を使用しないことになった場合でも「アルゴリズムとイテレーター」の
組み合わせさえしっかりできていれば他のベンダーのコンテナクラス( CArray とか)への
移行も簡単にできます。逆に、最初は配列でコードを書き、途中で std::vector へ
乗り換えることも簡単にできるでしょう。もし std::vector のメンバ関数を使用してしまうと、
これを配列や他のコンテナクラスに移行するのが非常に困難になります。
この問題を避けるために、アルゴリズムを使用して、後々の改変しやすさを保つことで
保守性を向上させているのです。STL において最も重要なのはアルゴリズムであり、
汎用性を高めてくれる関数オブジェクトやイテレーターとの連携です。
コンテナはこの連携に最適化されたクラスグループです。
「便利な脇役」として使いこなすことが、何より大事でしょう。


press Enter

http://www.cplusplus.com/forum/articles/7312/
#include 
#include 

void PressEnterToContinue()
{
  std::cout << "Press ENTER to continue... " << flush;
  std::cin.ignore( std::numeric_limits  ::max(), '\n' );
}



valarrayのよりもvectoryとfor_each

これでいい気がしてきた、いやぜんぜんそんなことなかった。
C++11の拡張でその場で関数をかけるので(lambda式って言うらしい)、これであんまりこまらないかも。

例えば、vectorに対するprintだったら、
template
std::ostream& operator<<(std::ostream& os, const std::vector& val)
{
  std::for_each(val.begin(), val.end(), [&os](T val){os << val << " ";});
  return os;
}

とか。lambda c++11で検索!!

valarrayのapply

戻り値を拾わないと内部の処理をそもそもしない。
これって結構えー、って感じなんですが。

valarrayのpow

しばらくハマった。しばらくは何か定義されてねーんじゃねと思ってしまった。
template valarray pow (const valarray& x, const valarray& y);
template valarray pow (const valarray& x, const T& y);

とreference?(http://www.cplusplus.com/reference/std/valarray/pow/)に書いてあるように、
第二引数はclass Tでなければならない。
doubleのvalarrayだったらdouble。これ結構きついなー。

これに起因する問題がもう一つ。
valarrayのvalarrayとかをして二次元配列がまっとうに作れるが、powだけは第二引数がややこしい。
vva_temp = std::pow(vva, std::valarray(3.,vva[0].size()));

とか。3のみのvalarrayを作ってそれをそれぞれのvalarrayに渡す。
もうひといき便利にならないかなー。

二次元配列(二重のvalarray)にしてしまうとsumとかmin,maxとかも普通には使えなくなる。
二次元にしたくても一次元にしておいてアクセスをgsliceでしろってことなのかなー。
なんだか。

有用サイト

http://docs.oracle.com/cd/E19205-01/820-2985/general/booktoc.htm
http://d.hatena.ne.jp/nokuno/20111017/1318803117
https://sites.google.com/site/siv3dgameengine/article/cpp11_first_step

C++0xって結局C++11って名前になったんですね

C++11ではvalarrayで初期化リストが使えるらしい。
僕らみたいにちょろちょろプログラミングしてる人にはvalarrayは丁度良さげ。
しばらく遊んでみようと思う。

stlとalgorithm,numeric

stl(vector)とかを使う場合はalgorithmとかnumericを使うとすごくオブジェクト指向っぽくなるのね。
全ての要素に足すってのも、for_eachと先頭を指すイテレータ、末尾を指すイテレータ、足し算を定義した関数オブジェクト
を渡せばいいと。
これ使わずして何がc++知ってますって話しだったのか。はずかしす。
未だに反復子ってのを理解してないしだめだ。。。時間あったらきっちりやりたい。

valarrayのgslice

http://www.cplusplus.com/reference/std/valarray/gslice/
この絵を見てやっと理解した。

valarray

配列に対してまとめて四則演算とかcosとか計算したいときに、
c,c++だとloopをまわしていたが、標準でvalarrayというのがあって、
標準的な関数は揃ってるっぽい。
知らなかった。
調べるとちょこちょこ文書が見つかる。

templateのexplicit instantiation

templateを使った場合、.hに実体を書かないとコンパイルが通らない。 だけど、以下の様にexplicitにtemplateをインスタンス化?するとソースコード側に書いても通るようになる。
    template void Func(int); 
とか。検索方法が分からなくてなかなか分からなかった。

データの羅列ファイルをvectorに読み込むシンプルなコード

物理とかのパラメータファイルは二次元の配列で ドバーッとファイルにデータがかかれていることがよくある。
これをシンプルなコードで動的配列に格納する方法。
ファイルが中程度までならvector、巨大な時はdequeを使うこと勧める。
途中'#'をコメントアウトとして読み飛ばしている。
int readin(std::string filename)
{
  std::ifstream ifs(filename.c_str());
  if(!ifs.is_open()){
     std::cout << filename << " dose not exist" << std::endl;
     return 0;
  }

  std::vector > xy;
  while(1){
    std::string str;
    std::getline(ifs, str);
    if(ifs.eof()) break;
    if(str.find("#") != std::string::npos) continue;
    std::istringstream iss(str);

    std::vector x;
    double xtemp;
    while(iss >> xtemp) x.push_back(xtemp);
    xy.push_back(x);
  }

  //print out
  std::vector >::iterator it = xy.begin();
  while(it != xy.end()){
    std::copy(it->begin(), it->end(), std::ostream_iterator(std::cout, " "));
    std::cout << std::endl;
    ++it;
  }

  return 1;
}


c++のバグ??続編

以下のコードの出力結果が信じられない。
#include 
#include 

int main()
{
  std::string a("a");
  std::string b = a;
  std::string c("a");

  printf("%p %p %p\n", a.c_str(), b.c_str(), c.c_str());

  return 0;
}

出力結果:0x9298014 0x9298014 0x929802c

環境はLinux, gccである。
つまり、std::stringのコピーは、内部で持っている文字列をコピーせずに、それを指すアドレスのみコピーしている。

そんで、それが原因でこんなことが起こりうる。
  std::string a("a");
  std::string b(a);

  strcpy((char*)(b.c_str()), "b");

  printf("%s %s\n", a.c_str(), b.c_str());

出力結果:b b 

これ、だめでしょ。
コピーコンストラクタ読んでいるので、完全に分離できていると思ってたのが、
実はその先のコードでこういうことやられると正常ではなくなる。
まじありえない。
ということでストリングのコピーコンストラクタは使えないってことだーーーー。

とりあえず解決するには、
std::string b(a);
std::string b(a.c_str());

としてしまえば、あたらしく中身が作られるので出力結果は"a b"となる。
これって既知の問題なのかな?
偉い人教えて。

で、なんかgoogle先生に効いたらそれっぽい話が。
http://d.hatena.ne.jp/s-yata/20110109/1294627973
んー、物理・計算系の人間でもこのくらい知らないといけないのか。

gcc4.5だけど。。。。

なんかガチでよくわからんので、とりあえずコピーコンストラクタがよばれるところはstring::c_str()を渡すことにした。

c++のバグ??

どうも、
std::string a("a"),b("b"),c("c");
s += a + c;

がダメなときがあるっぽい。
ちがうところでメモリ侵略がはじまってて、それが露呈しただけか。。。

んーーーーーー、たぶん違うところに原因が。うわーーーーー。

program関連


cとfのやりとりで、配列のわたし方。
先頭アドレスと配列の大きさを渡せばいいけど、 並び順に注意。

fのcommonをcに渡すときに、 common/c_aa/ とか、ハイフン付きの名前にするとだめっぽい。
mapはconst指定で渡せない時がある。 これは、キーの参照をしたときに、そのキーが存在しないと 勝手にそのキーを登録するからと考えられる。 このため、見掛け上は参照しかしてないのでconstで渡せるように思えるが、 実はコンパイルエラーになるという罠。